lapply in list - 将rownames设置为NULL

时间:2015-08-02 11:33:55

标签: r

我有一个如下所示的列表。现在我正在尝试将列表的每个data.frame中的所有rownames设置为NULL,以便每个data.frame以1开头的rowname开头。但不知何故,它没有正确执行。

我的la la声明有些不对劲,但我无法弄清楚是什么。

代码

  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中的rownames不会按预期以1开头。但是分别来自split function的索引号。

1 个答案:

答案 0 :(得分:4)

只需使用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与任何其他函数没有区别。在您的情况下,这意味着lambda的x参数成为原始列表by.areaSize的每个元素的lambda,IOW的每个评估的新局部变量。对x变量进行更改不会影响原始列表by.areaSize,因为by.areaSize是一个单独的变量,它是外部函数评估环境的本地变量(指您的函数20function())。

如果您确实想使用lapply()来完成此任务,可以采用两种方法。首先,您可以迭代原始列表的索引(或名称),而不是其元素,并使用超级对齐运算符<<-索引分配原始列表,该运算符搜索闭包环境链,直到找到LHS变量名称的匹配(或者,如果找不到,将在全局环境中创建一个新的此类变量)。这类似于我上面用for循环所做的,除了我没有必要使用超级赋值运算符,因为我没有内部函数范围需要担心。以下是它的外观:

lapply(seq_along(by.areaSize),function(x) rownames(by.areaSize[[x]]) <<- NULL);

或者,您可以使用lapply()调用的返回值覆盖整个原始列表,这样您就可以有效地重建&#34;重建&#34;包含从lambda返回的任何值的列表。在您的情况下,您可能希望修改x的行名称,然后返回x本身。目前,您的lambda实际上返回了本地赋值操作的返回值,这是RHS的值,在您的情况下为NULL。显然,这不是你想要的。以下是如何执行此操作:

by.areaSize <- lapply(by.areaSize,function(x) { rownames(x) <- NULL; x; });