使用lapply over data.tables列表将列表成员名称指定为变量

Dav*_*RGP 1 r list apply data.table

我有一个data.tables列表

library(data.table)

set.seed(27)
test <- list()
test$a <- data.table(x = rnorm(n = 10),
                     y = rnorm (n = 10))
test$b <- data.table(x = rnorm(n = 10),
                     y = rnorm (n = 10))
Run Code Online (Sandbox Code Playgroud)

列表的每个成员都有一个唯一的名称

test
Run Code Online (Sandbox Code Playgroud)

为了准备将这些多个表附加到单个"long"格式中,我想创建一个第三列,它是一个变量,它是通过函数的每个成员的名称(我需要定期执行此操作).

目前工作(虽然不正确)代码:

lName.asVariable <- function(dataTableList) {
dataTableList <- lapply(X = dataTableList, FUN = function(x)(x[, Site :=names(dataTableList)]))
}

test <- lName.asVariable(test)
test
Run Code Online (Sandbox Code Playgroud)

哪个输出

$a
               x           y Site
 1:  1.907162564 -1.28512736    a
 2:  1.144876890  0.03482725    b
 3: -0.764530737  1.57029534    a
 4: -1.457432503  0.15801005    b
...
$b
              x          y Site
 1: -0.57488122 -0.1520452    a
 2: -1.15190000 -0.9589459    b
 3:  0.08706853  1.8582198    a
 4: -0.07018075 -1.5747647    b
...
Run Code Online (Sandbox Code Playgroud)

虽然我想要的是

$a
               x           y Site
 1:  1.907162564 -1.28512736    a
 2:  1.144876890  0.03482725    a
 3: -0.764530737  1.57029534    a
 4: -1.457432503  0.15801005    a
...
$b
              x          y Site
 1: -0.57488122 -0.1520452    b
 2: -1.15190000 -0.9589459    b
 3:  0.08706853  1.8582198    b
 4: -0.07018075 -1.5747647    b
...
Run Code Online (Sandbox Code Playgroud)

从列表中 读取对象的提取名称seq_along可能是我需要的,但以下代码会产生错误:

lName.asVariable <- function(dataTableList) {
    dataTableList <- lapply(X = seq_along(dataTableList), FUN = function(x)(x[, Site := names(dataTableList)]))
}

test <- lName.asVariable(test)
test
Run Code Online (Sandbox Code Playgroud)

我不够锐利,但要弄清楚如何打包seq_alongdata.table正确引用.这甚至是正确的策略吗?

Jam*_*mes 6

seq_along生成从1到列表长度的数字序列.然后,您可以使用中间索引变量来引用列表项和names项:

lapply(seq_along(test), function(i) test[[i]][,Site:=names(test[i])])
[[1]]
               x           y Site
 1:  1.907162564 -1.28512736    a
 2:  1.144876890  0.03482725    a
 3: -0.764530737  1.57029534    a
 4: -1.457432503  0.15801005    a
 5: -1.093468881 -0.74579947    a
 6:  0.295241218 -1.06880297    a
 7:  0.006885942 -1.62743793    a
 8:  1.157410886 -1.06858164    a
 9:  2.134637891 -0.02583971    a
10:  0.237844613  0.31957639    a

[[2]]
              x          y Site
 1: -0.57488122 -0.1520452    b
 2: -1.15190000 -0.9589459    b
 3:  0.08706853  1.8582198    b
 4: -0.07018075 -1.5747647    b
 5: -2.99830401 -0.3981480    b
 6: -1.22399491  0.9686850    b
 7: -0.99707477  0.6711891    b
 8:  0.33571390  0.6788910    b
 9:  1.29534374 -0.1739613    b
10:  0.32775994  0.7890292    b
Run Code Online (Sandbox Code Playgroud)

请注意,lapply的输出会丢失名称,因此您必须手动恢复它们.

  • 我可能是错的,因为我不习惯“data.table”,但在赋值中使用方括号“[]”可以保留名称,即“test[] &lt;- lapply(seq_along(test), function(i) test[ [i]][,Site:=names(test[i])])`,因此无需以这种方式手动恢复它们。 (2认同)
  • 我认为,for循环中的相同内容会更好.我猜`lapply`会产生一个数据副本(因为它有一个返回值).`for(i in seq_along(test){test [[i]] [,Site:= names(test [i])]}` (2认同)