我有一个如下所示的列表。现在,我尝试将列表中每个 data.frame 中的所有行名称设置为 NULL,以便每个 data.frame 都以 1 开头,因为它是行名称。但不知何故它无法正确执行。
我的 lapply 语句有问题,但我不知道是什么问题。
代码
20function <- function (return.query) {
by.areaSize <- split(return.query, return.query$areaSize, drop = FALSE)
lapply(by.areaSize, FUN = function(x) rownames(x) <- NULL)
return(by.areaSize)
}
我正在应用 lapply 的列表
summary(x.split)
Length Class Mode
0 28 data.frame list
10 28 data.frame list
20 28 data.frame list
30 28 data.frame list
40 28 data.frame list
50 28 data.frame list
60 28 data.frame list
70 28 data.frame list
80 28 data.frame list
90 28 data.frame list
100 28 data.frame list
110 28 data.frame list
120 28 data.frame list
130 28 data.frame list
140 28 data.frame list
150 28 data.frame list
160 28 data.frame list
170 28 data.frame list
180 28 data.frame list
190 28 data.frame list
200 28 data.frame list
210 28 data.frame list
220 28 data.frame list
230 28 data.frame list
250 28 data.frame list
260 28 data.frame list
270 28 data.frame list
280 28 data.frame list
300 28 data.frame list
330 28 data.frame list
在我的 lapply 之后,每个 data.frame 中的 rowname 并未按预期以 1 开头。而是分别通过 split 函数
中的索引号。
最佳答案
只需使用 for
环形;不需要lapply()
这里:
list.of.dfs <- list(`0`=data.frame(a=1:3,b=letters[1:3],row.names=rnorm(3)),`10`=data.frame(x=4:6,y=letters[4:6],row.names=rnorm(3)));
list.of.dfs;
## $`0`
## a b
## 0.0498607222485908 1 a
## 0.97522800355155 2 b
## 0.128524519534542 3 c
##
## $`10`
## x y
## -0.869665657970296 4 d
## 1.45087559347205 5 e
## 0.70259805976925 6 f
##
summary(list.of.dfs);
## Length Class Mode
## 0 2 data.frame list
## 10 2 data.frame list
for (i in seq_along(list.of.dfs)) rownames(list.of.dfs[[i]]) <- NULL;
list.of.dfs;
## $`0`
## a b
## 1 1 a
## 2 2 b
## 3 3 c
##
## $`10`
## x y
## 1 4 d
## 2 5 e
## 3 6 f
##
让我尝试解释一下您的代码中发生了什么。首先,了解 R 范围规则很重要。任何函数的每次调用都会导致为该特定函数求值创建一个求值环境,并且在该函数求值期间分配的所有局部变量都存储在该环境中。函数参数也存储在该环境中。 lapply()
的 lambda call 与任何其他函数没有什么不同。在您的情况下,这意味着 x
lambda 的参数成为每次 lambda 计算的新局部变量,对于原始列表的每个元素 by.areaSize
IOW 。更改 x
变量对原始列表没有影响 by.areaSize
,因为by.areaSize
是一个单独的变量,它是外部函数的评估环境的本地变量(指您的函数 20function()
)。
如果你确实想使用lapply()
要完成此任务,您可以采取两种方法。首先,您可以迭代原始列表的索引(或名称),而不是其元素,并使用 super 赋值运算符 <<-
对原始列表进行索引分配。 ,它搜索闭包环境链,直到找到 LHS 变量名称的匹配项(或者,如果没有找到,将在全局环境中创建一个新的此类变量)。这与我上面对 for
所做的类似循环,除了我不必在那里使用 super 赋值运算符,因为我没有内部函数作用域需要担心。其外观如下:
lapply(seq_along(by.areaSize),function(x) rownames(by.areaSize[[x]]) <<- NULL);
或者,您可以使用 lapply()
的返回值覆盖整个原始列表。调用,这将允许您使用从 lambda 返回的任何值有效地“重建”列表。在您的情况下,您需要修改 x
的行名称然后返回x
本身。目前,您的 lambda 实际上返回本地赋值操作的返回值,即 RHS 的值,在您的情况下为 NULL。显然这不是你想要的。执行此操作的方法如下:
by.areaSize <- lapply(by.areaSize,function(x) { rownames(x) <- NULL; x; });
关于r - lapply in list - 将行名设置为 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31771483/