【问题标题】:lapply in list - setting rownames to NULLlapply in list - 将行名设置为 NULL
【发布时间】:2015-08-02 11:33:55
【问题描述】:

我有一个如下所示的列表。现在我正在尝试将列表的每个 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)
}

我要申请的列表

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 中的行名并未按预期以 1 开头。但是它们的索引号分别来自split function

【问题讨论】:

  • 你需要一个返回 (x) 即lapply(by.areaSize, FUN = function(x) {rownames(x) &lt;- NULL);x })

标签: r


【解决方案1】:

只需使用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 参数成为每个 lambda 评估的新局部变量,IOW 用于原始列表 by.areaSize 的每个元素。更改x 变量不会影响原始列表by.areaSize,因为by.areaSize 是一个单独的变量,它是外部函数评估环境的本地变量(指您的函数20function())。

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

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; });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    相关资源
    最近更新 更多