Nếu bạn muốn khai báo như vậy data.framevớ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)
lapplysẽ 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().
setDFchuyển đổi điều này listbằ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 structuretheo 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