Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List data.frame将行添加到列表中_List_R_Dataframe - Fatal编程技术网

List data.frame将行添加到列表中

List data.frame将行添加到列表中,list,r,dataframe,List,R,Dataframe,我有一个data.frame,我想将它转换成一个逐行列表,这意味着每一行都对应于它自己的列表元素。换句话说,我想要一个与data.frame有行一样长的列表 到目前为止,我已经用以下方式解决了这个问题,但我想知道是否有更好的方法来解决这个问题 xy.df <- data.frame(x = runif(10), y = runif(10)) # pre-allocate a list and fill it with a loop xy.list <- vector("list"

我有一个data.frame,我想将它转换成一个逐行列表,这意味着每一行都对应于它自己的列表元素。换句话说,我想要一个与data.frame有行一样长的列表

到目前为止,我已经用以下方式解决了这个问题,但我想知道是否有更好的方法来解决这个问题

xy.df <- data.frame(x = runif(10),  y = runif(10))

# pre-allocate a list and fill it with a loop
xy.list <- vector("list", nrow(xy.df))
for (i in 1:nrow(xy.df)) {
    xy.list[[i]] <- xy.df[i,]
}
xy.dfEureka

xy.list <- as.list(as.data.frame(t(xy.df)))

xy.list如果您想完全滥用data.frame(如我所做)并想保留$function,一种方法是将data.frame拆分为一行data.frames,收集在列表中:

> df = data.frame(x=c('a','b','c'), y=3:1)
> df
  x y
1 a 3
2 b 2
3 c 1

# 'convert' into a list of data.frames
ldf = lapply(as.list(1:dim(df)[1]), function(x) df[x[1],])

> ldf
[[1]]
x y
1 a 3    
[[2]]
x y
2 b 2
[[3]]
x y
3 c 1

# and the 'coolest'
> ldf[[2]]$y
[1] 2
它不仅是一种智能手淫,而且允许将data.frame“转换”为其行列表,保留$indexation,这对Lappy的进一步使用非常有用(假设传递给Lappy的函数使用此$indexation)

如下:

xy.list <- split(xy.df, seq(nrow(xy.df)))

另一种方法是将df转换为矩阵,然后在其上应用list apply
lappy
函数:
ldf另一种方法是使用
library(purr)
(这在大数据帧上似乎要快一点)


似乎当前版本的
purr
(0.2.2)包是最快的解决方案:

by_row(x,函数(v)list(v)[[1L]],.collate=“list”)$.out
让我们比较一下最有趣的解决方案:

数据(“击球”,package=“Lahman”)

来自
purrlyr
软件包的
by_row
功能将为您完成此操作

这个例子演示了

myfn <- function(row) {
  #row is a tibble with one row, and the same number of columns as the original df
  l <- as.list(row)
  return(l)
}

list_of_lists <- purrrlyr::by_row(df, myfn, .labels=FALSE)$.out

myfn对我来说最好的方法是:

示例数据:

Var1<-c("X1",X2","X3")
Var2<-c("X1",X2","X3")
Var3<-c("X1",X2","X3")

Data<-cbind(Var1,Var2,Var3)

ID    Var1   Var2  Var3 
1      X1     X2    X3
2      X4     X5    X6
3      X7     X8    X9
结果将是:

ID    Var1   Var2  Var3  lists
1      X1     X2    X3   list("X1", "X2", X3") 
2      X4     X5    X6   list("X4","X5", "X6") 
3      X7     X8    X9   list("X7,"X8,"X9) 
就像@flodel写的: 这会将dataframe转换为一个列表,该列表的元素数与dataframe中的行数相同:

NewList <- split(df, f = seq(nrow(df)))

NewList更现代的解决方案只使用
purrr::transpose

库(purrr)
虹膜[1:2,]%>%purrr::transpose()
#> [[1]]
#>[[1]]$萼片长度
#> [1] 5.1
#> 
#>[[1]]$萼片宽度
#> [1] 3.5
#> 
#>[[1]]$Petal.Length
#> [1] 1.4
#> 
#>[[1]]$Petal.Width
#> [1] 0.2
#> 
#>[[1]]$种
#> [1] 1
#> 
#> 
#> [[2]]
#>[[2]]$萼片长度
#> [1] 4.9
#> 
#>[[2]]$萼片宽度
#> [1] 3
#> 
#>[[2]]$Petal.Length
#> [1] 1.4
#> 
#>[[2]]$Petal.Width
#> [1] 0.2
#> 
#>[[2]]$种
#> [1] 1

我今天正在为一个data.frame(实际上是一个data.table)做这个,它有数百万个观察值和35列。我的目标是返回一个data.frames(data.tables)列表,每个列表只包含一行。也就是说,我想将每一行拆分为一个单独的data.frame,并将其存储在一个列表中

以下是我提出的两种方法,对于该数据集,它们的速度大约是
split(dat,seq_len(nrow(dat))
的3倍。下面,我在7500行5列数据集(iris重复50次)上对这三种方法进行基准测试

虽然差异没有我之前的测试中那么大,但是在最大(setDF)setDF
方法的速度明显更快,而
attr
方法的速度通常是前者的两倍以上

第四种方法是extrementchampion,它是一个简单的嵌套
lappy
,返回一个嵌套列表。此方法举例说明了从列表构造data.frame的成本。此外,我用
data.frame
函数尝试的所有方法都比
data.table
技术慢一个数量级

数据

dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
set.seed(1234)
xy.df <- data.frame(x = runif(10),  y = runif(10))

dat还有几个选项:

使用
asplit

asplit(xy.df, 1)
#[[1]]
#     x      y 
#0.1137 0.6936 

#[[2]]
#     x      y 
#0.6223 0.5450 

#[[3]]
#     x      y 
#0.6093 0.2827 
#....

使用
拆分

split(xy.df, row(xy.df)[, 1])

#$`1`
#       x      y
#1 0.1137 0.6936

#$`2`
#       x     y
#2 0.6223 0.545

#$`3`
#       x      y
#3 0.6093 0.2827
#....
数据

dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
set.seed(1234)
xy.df <- data.frame(x = runif(10),  y = runif(10))
set.seed(1234)

xy.df是否愿意演示如何使用apply?
unlist(apply(xy.df,1,list),recursive=FALSE)
。然而,flodel的解决方案比使用
apply
t
更有效。这里的问题是
t
数据.fame
转换为
矩阵
,因此列表中的元素是原子向量,而不是OP请求的列表。在
xy.df
包含混合类型之前,这通常不是一个问题……如果要循环使用这些值,我不建议
apply
。实际上,它只是在R中实现的for循环。
lappy
在C中执行循环,速度明显更快。如果要执行大量循环,则此行列表格式实际上更可取。添加来自未来的另一条注释,
apply
版本是
.mapply(data.frame,xy.df,NULL)
如何将它们重新组合在一起?将
data.frame
s列表转换为单个
data.frame
?@AaronMcDaid您可以使用do.call和rbind:df==do.call(“rbind”,ldf)@AaronMcDaid或data.table::rbindlist()。如果您的原始数据帧很大,那么速度将显著提高。在150行的微小数据集上进行基准测试没有多大意义,因为没有人会注意到微秒的差异,而且它不会按行缩放。
现在已移动到
库(purrlyr)
,除了处于purrlyr中,它即将被弃用。现在还有其他方法结合了tidyr::nest、dplyr::mutate purrr::map来实现相同的结果,`by_row()`现在已经移动到`library(purrlyr)`注意,使用
split
后,每个元素都有类型
data.frame,有1行和N列
而不是
长度N的列表
,我只想补充一点,如果使用
split
您可能应该执行
drop=T
,否则您的原始因子水平不会下降我的xy.df完全是数字。asplit(xy.df,1)给了我一个数字列表。拆分(xy.df,f=seq(nrow(xy.df)))未执行。谢谢
NewList2 <- lapply(NewList, function(x) x[,!is.na(x)])
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
dat <- vector("list", 50)
for(i in 1:50) dat[[i]] <- iris
dat <- setDF(rbindlist(dat))
asplit(xy.df, 1)
#[[1]]
#     x      y 
#0.1137 0.6936 

#[[2]]
#     x      y 
#0.6223 0.5450 

#[[3]]
#     x      y 
#0.6093 0.2827 
#....
split(xy.df, row(xy.df)[, 1])

#$`1`
#       x      y
#1 0.1137 0.6936

#$`2`
#       x     y
#2 0.6223 0.545

#$`3`
#       x      y
#3 0.6093 0.2827
#....
set.seed(1234)
xy.df <- data.frame(x = runif(10),  y = runif(10))