在R中创建列表列表的有效方法

时间:2015-09-01 16:39:32

标签: r list

我想从数据框创建列表列表。我可以使用for循环执行此操作:

n <- 5
df <- data.frame(x = rnorm(n), y = rnorm(n), N = sample(10:50,n))

expList <- vector("list", n)
for (i in 1:n)
{
  expList[[i]]$par$x <- df$x[i]
  expList[[i]]$par$y <- df$y[i]
  expList[[i]]$N <- df$N[i]
  class(expList[[i]]) <- c(class(expList[[i]]), "Experiment")
}

结果应如下所示:

expList

[[1]]
$par
$par$x
[1] 2.574112

$par$y
[1] -2.33903


$N
[1] 36

attr(,"class")
[1] "list"       "Experiment"

[[2]]
$par
$par$x
[1] -0.264593

$par$y
[1] 0.5924768
    .........

我正在寻找一种创建此列表的有效方法(假设为n = 10e7)。这样的事情:expList[1:n]$par$x <- df$x(我知道这是错的)。

4 个答案:

答案 0 :(得分:2)

你可以Map。结合您的类和do.call的构造函数,这非常简洁,似乎比问题中的解决方案快几倍。

experiment<-function(x,y,N)
  structure(list(par=list(x=x,y=y),N=N),class="Experiment")

L<-do.call(Map,c(f=experiment,df))
str(L)
List of 5
 $ :List of 2
  ..$ par:List of 2
  .. ..$ x: num -0.754
  .. ..$ y: num -0.768
  ..$ N  : int 27
  ..- attr(*, "class")= chr "Experiment"
 $ :List of 2
  ..$ par:List of 2
  .. ..$ x: num 0.487
  .. ..$ y: num -1.31
  ..$ N  : int 23
  ..- attr(*, "class")= chr "Experiment"
 $ :List of 2
  ..$ par:List of 2
  .. ..$ x: num -0.653
  .. ..$ y: num -0.2
  ..$ N  : int 35
  ..- attr(*, "class")= chr "Experiment"
 $ :List of 2
  ..$ par:List of 2
  .. ..$ x: num -0.687
  .. ..$ y: num -0.441
  ..$ N  : int 17
  ..- attr(*, "class")= chr "Experiment"
 $ :List of 2
  ..$ par:List of 2
  .. ..$ x: num -0.0851
  .. ..$ y: num -0.665
  ..$ N  : int 24
  ..- attr(*, "class")= chr "Experiment"

数据

df<-structure(list(x = c(-0.754391843396212, 0.487237170179346, -0.653098590457105, 
-0.686632907020112, -0.0850559453983232), y = c(-0.767944417138587, 
-1.31042221234913, -0.199621075494168, -0.441313470125542, -0.664834248101919
), N = c(27L, 23L, 35L, 17L, 24L)), .Names = c("x", "y", "N"), row.names = c(NA, 
-5L), class = "data.frame")

答案 1 :(得分:0)

你对DF的每一行列表都没问题吗?即。

for (i in 1:n) {
  expList[[i]] <- df[i, ]
}

因为您仍然可以访问每个列表中的这些变量。或者您的示例数据与您的真实数据不一样(类似格式)?

答案 2 :(得分:0)

# library(dplyr), otherwise just do lapply(split(df, 1:n), as.list)
split(df, 1:n) %>% lapply(as.list) 

> str(.Last.value)
List of 5
 $ 1:List of 3
  ..$ x: num 0.979
  ..$ y: num -0.358
  ..$ N: int 23
 $ 2:List of 3
  ..$ x: num -0.0297
  ..$ y: num 0.589
  ..$ N: int 21
 So on...

使用lapply(function (x) {blah})在每个列表上操作。我觉得在R中有10e7个列表可能不太理想。

答案 3 :(得分:0)

试试这个解决方案:

apply(df, 1L, function(x) {
    result <- as.list(x)
    class(result) <- c(class(result), "Experiment")
    result
})