我有一个列表,如下所示。现在我尝试将列表中每个 data.frame 中的所有 rowname 设置为NULL,以便每个 data.frame 都以 1 开头,因为它是 rowname。但不知何故它无法正确执行。
我的 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)
}
Run Code Online (Sandbox Code Playgroud)
我正在申请 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
Run Code Online (Sandbox Code Playgroud)
仍然在我的 lapply 之后,每个 data.frame 中的 rowname 并未按预期以 1 开头。而是分别通过它们的索引号split function。
只需使用一个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
##
Run Code Online (Sandbox Code Playgroud)
让我尝试解释一下您的代码中发生了什么。首先,了解 R 范围规则很重要。任何函数的每次调用都会导致为该特定函数求值创建一个求值环境,并且在该函数求值期间分配的所有局部变量都存储在该环境中。函数参数也存储在该环境中。调用的 lambdalapply()与任何其他函数没有什么不同。在您的情况下,这意味着xlambda 的参数成为每次 lambda 求值的新局部变量,即原始 list 的每个元素的 IOW by.areaSize。对变量进行更改x对原始 list 没有影响by.areaSize,因为by.areaSize它是一个单独的变量,对于外部函数的评估环境(指的是您的 function 20function())而言是本地的。
如果您确实想用来lapply()完成此任务,可以采取两种方法。首先,您可以迭代原始列表的索引(或名称),而不是其元素,并使用超级赋值运算符对原始列表进行索引分配<<-,该运算符搜索闭包环境链,直到找到 LHS 变量的匹配项name(或者,如果没有找到,将在全局环境中创建一个新的此类变量)。这与我上面对循环所做的类似for,只是我不必在那里使用超级赋值运算符,因为我不需要担心内部函数作用域。看起来是这样的:
lapply(seq_along(by.areaSize),function(x) rownames(by.areaSize[[x]]) <<- NULL);
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用调用的返回值覆盖整个原始列表lapply(),这将允许您使用从 lambda 返回的任何值有效地“重建”列表。在您的情况下,您需要修改 的行名称x,然后返回x其本身。目前,您的 lambda 实际上返回本地赋值操作的返回值,即 RHS 的值,在您的情况下为 NULL。显然这不是你想要的。执行此操作的方法如下:
by.areaSize <- lapply(by.areaSize,function(x) { rownames(x) <- NULL; x; });
Run Code Online (Sandbox Code Playgroud)