重命名多个数据帧中的列,R

use*_*593 8 r dataframe

我正在尝试重命名多个列的列data.frame.

举个例子,假设我有一个data.frames 列表dfA,dfBdfC.我写了一个函数changeNames来相应地设置名称,然后使用lapply如下:

dfs <- list(dfA, dfB, dfC)
ChangeNames <- function(x) {
    names(x) <- c("A", "B", "C" )  
}
lapply(dfs, ChangeNames)
Run Code Online (Sandbox Code Playgroud)

但是,这不能按预期工作.似乎我没有为其分配新名称data.frame,而只是创建新名称.我在这做错了什么?

先感谢您!

Aru*_*run 13

这里有两件事:

  • 1)您应该从函数中返回所需的值.否则,将返回最后一个值.在你的情况下,那是names(x).所以,你应该添加最后一行,return(x)或者简单地添加x.所以,你的功能看起来像:

    ChangeNames <- function(x) {
        names(x) <- c("A", "B", "C" )
        return(x)
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 2)lapply不会通过引用修改输入对象.它适用于副本.因此,您必须重新分配结果.或者另一种方法是使用for-loops而不是lapply:

    # option 1
    dfs <- lapply(dfs, ChangeNames)
    
    # option 2
    for (i in seq_along(dfs)) {
        names(dfs[[i]]) <- c("A", "B", "C")
    }
    
    Run Code Online (Sandbox Code Playgroud)

即使使用for-loop,你仍然会复制(因为names(.) <- .).您可以使用以验证这一点tracemem.

df <- data.frame(x=1:5, y=6:10, z=11:15)
tracemem(df)
# [1] "<0x7f98ec24a480>"
names(df) <- c("A", "B", "C")
tracemem(df)
# [1] "<0x7f98e7f9e318>"
Run Code Online (Sandbox Code Playgroud)

如果要通过引用进行修改,可以使用data.table包的setnames功能:

df <- data.frame(x=1:5, y=6:10, z=11:15)
require(data.table)
tracemem(df)
# [1] "<0x7f98ec76d7b0>"
setnames(df, c("A", "B", "C"))
tracemem(df)
# [1] "<0x7f98ec76d7b0>"
Run Code Online (Sandbox Code Playgroud)

您看到df映射到的内存位置未更改.名称已通过参考修改.


JWi*_*man 10

如果数据帧不在列表中但仅在全局环境中,则可以使用字符串名称向量引用它们.

dfs <- c("dfA", "dfB", "dfC")

for(df in dfs) {
  df.tmp <- get(df)
  names(df.tmp) <- c("A", "B", "C" ) 
  assign(df, df.tmp)
}
Run Code Online (Sandbox Code Playgroud)

可能有一种方法可以简化这一过程,而无需求助于创建临时数据集,但我还没有解决这个问题!