我正在尝试重命名多个data.frame
的列。
举一个例子,假设我列出了data.frame
s dfA
,dfB
和dfC
。我编写了一个函数changeNames
来相应地设置名称,然后使用lapply
,如下所示:
dfs <- list(dfA, dfB, dfC)
ChangeNames <- function(x) {
names(x) <- c("A", "B", "C" )
}
lapply(dfs, ChangeNames)
但是,这不能按预期工作。似乎我没有将新名称分配给data.frame
,而只是创建新名称。我在这里做错了什么?
提前谢谢!
答案 0 :(得分:13)
这里有两件事:
1)您应该从函数中返回所需的值。否则,将返回最后一个值。在你的情况下,那是names(x)
。因此,您应该添加最后一行return(x)
或简单x
。所以,你的功能看起来像:
ChangeNames <- function(x) {
names(x) <- c("A", "B", "C" )
return(x)
}
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")
}
即使使用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>"
如果您想通过引用进行修改,可以使用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>"
您看到映射到的内存位置df
未更改。名称已通过参考修改。
答案 1 :(得分:7)
如果数据帧不在列表中但只在全局环境中,则可以使用字符串名称向量引用它们。
dfs <- c("dfA", "dfB", "dfC")
for(df in dfs) {
df.tmp <- get(df)
names(df.tmp) <- c("A", "B", "C" )
assign(df, df.tmp)
}
可能有一种方法可以简化这一过程,而无需求助于创建临时数据集,但我还没有解决这个问题!
答案 2 :(得分:-1)
我遇到了导入公共数据集并且必须重命名每个数据帧并重命名每个数据框中的每一列以修剪空格,小写和用句点替换内部空格的问题。
结合上述方法让我:
for (eachdf in dfs)
df.tmp <- get(eachdf)
for (eachcol in 1:length(df.tmp))
colnames(df.tmp)[eachcol] <-
str_trim(str_to_lower(str_replace_all(colnames(df.tmp)[eachcol], " ", ".")))
}
assign(eachdf, df.tmp)
}