3 回答
TA贡献1853条经验 获得超6个赞
像这样:
xy.list <- split(xy.df, seq(nrow(xy.df)))
而且,如果希望xy.df将行名作为输出列表的名称,则可以执行以下操作:
xy.list <- setNames(split(xy.df, seq(nrow(xy.df))), rownames(xy.df))
TA贡献1895条经验 获得超7个赞
今天,我正在为一个具有数百万个观测值和35列的data.frame(实际上是一个data.table)进行此工作。我的目标是返回一个data.frames(data.tables)列表,每个列表只有一行。也就是说,我想将每一行拆分为一个单独的data.frame并将它们存储在列表中。
这是我想出的两种方法,它们的速度大约比split(dat, seq_len(nrow(dat)))该数据集快3倍。下面,我在7500行,5列数据集上对这三种方法进行了基准测试(虹膜重复了50次)。
library(data.table)
library(microbenchmark)
microbenchmark(
split={dat1 <- split(dat, seq_len(nrow(dat)))},
setDF={dat2 <- lapply(seq_len(nrow(dat)),
function(i) setDF(lapply(dat, "[", i)))},
attrDT={dat3 <- lapply(seq_len(nrow(dat)),
function(i) {
tmp <- lapply(dat, "[", i)
attr(tmp, "class") <- c("data.table", "data.frame")
setDF(tmp)
})},
datList = {datL <- lapply(seq_len(nrow(dat)),
function(i) lapply(dat, "[", i))},
times=20
)
这返回
Unit: milliseconds
expr min lq mean median uq max neval
split 861.8126 889.1849 973.5294 943.2288 1041.7206 1250.6150 20
setDF 459.0577 466.3432 511.2656 482.1943 500.6958 750.6635 20
attrDT 399.1999 409.6316 461.6454 422.5436 490.5620 717.6355 20
datList 192.1175 201.9896 241.4726 208.4535 246.4299 411.2097 20
尽管差异没有我以前的测试中的大,但是setDF在max(setDF)<min(split)的运行分布的所有级别上,直接方法都明显更快,并且该attr方法通常快两倍以上。
第四种方法是极端冠军,它是一个简单的嵌套lapply,返回嵌套列表。此方法举例说明了从列表构造data.frame的成本。而且,我使用该data.frame函数尝试的所有方法都比data.table技术慢了一个数量级。
数据
dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
- 3 回答
- 0 关注
- 610 浏览
添加回答
举报