Nếu bạn muốn khai báo như vậy data.frame
với nhiều cột, có thể sẽ rất khó để nhập tất cả các lớp cột bằng tay. Đặc biệt nếu bạn có thể sử dụng rep
, phương pháp này rất dễ dàng và nhanh chóng (nhanh hơn khoảng 15% so với giải pháp khác có thể khái quát như thế này):
Nếu các lớp cột mong muốn của bạn nằm trong một vectơ colClasses
, bạn có thể làm như sau:
library(data.table)
setnames(setDF(lapply(colClasses, function(x) eval(call(x)))), col.names)
lapply
sẽ dẫn đến một danh sách độ dài mong muốn, mỗi phần tử chỉ đơn giản là một vectơ gõ trống như numeric()
hoặc integer()
.
setDF
chuyển đổi điều này list
bằng cách tham chiếu đến a data.frame
.
setnames
thêm tên mong muốn bằng cách tham khảo.
So sánh tốc độ:
classes <- c("character", "numeric", "factor",
"integer", "logical","raw", "complex")
NN <- 300
colClasses <- sample(classes, NN, replace = TRUE)
col.names <- paste0("V", 1:NN)
setDF(lapply(colClasses, function(x) eval(call(x))))
library(microbenchmark)
microbenchmark(times = 1000,
read = read.table(text = "", colClasses = colClasses,
col.names = col.names),
DT = setnames(setDF(lapply(colClasses, function(x)
eval(call(x)))), col.names))
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# read 2.598226 2.707445 3.247340 2.747835 2.800134 22.46545 1000 b
# DT 2.257448 2.357754 2.895453 2.401408 2.453778 17.20883 1000 a
Nó cũng nhanh hơn sử dụng structure
theo cách tương tự:
microbenchmark(times = 1000,
DT = setnames(setDF(lapply(colClasses, function(x)
eval(call(x)))), col.names),
struct = eval(parse(text=paste0(
"structure(list(",
paste(paste0(col.names, "=",
colClasses, "()"), collapse = ","),
"), class = \"data.frame\")"))))
#Unit: milliseconds
# expr min lq mean median uq max neval cld
# DT 2.068121 2.167180 2.821868 2.211214 2.268569 143.70901 1000 a
# struct 2.613944 2.723053 3.177748 2.767746 2.831422 21.44862 1000 b