为了账号安全,请及时绑定邮箱和手机立即绑定

data.frame行到列表

data.frame行到列表

MM们 2019-10-25 15:28:09
我有一个data.frame,我想按行将其转换为列表,这意味着每行将对应于其自己的列表元素。换句话说,我想要一个只要data.frame有行的列表。到目前为止,我已经按照以下方式解决了这个问题,但是我想知道是否有更好的方法来解决这个问题。xy.df <- data.frame(x = runif(10),  y = runif(10))# pre-allocate a list and fill it with a loopxy.list <- vector("list", nrow(xy.df))for (i in 1:nrow(xy.df)) {    xy.list[[i]] <- xy.df[i,]}
查看完整描述

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))


查看完整回答
反对 回复 2019-10-25
?
人到中年有点甜

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))


查看完整回答
反对 回复 2019-10-25
  • 3 回答
  • 0 关注
  • 569 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信