使用数据框列表将函数应用于列名

时间:2016-11-02 21:44:29

标签: r

我试图将一个非常复杂的函数应用于超过50个数据框的列表。 为了清楚起见,我们使用一个非常简单的函数来小写名称和3个数据帧,但我的一般方法编码如下

[EDITED NAMES]
# Data Sample. Every column name is different accross Data Frames


quality <- data.frame(FIRST=c(1,5,3,3,2), SECOND=c(3,6,1,5,5))
thickness <- data.frame(THIRD=c(6,0,9,1,2), FOURTH=c(2,7,2,2,1))
distance <- data.frame(ONEMORE=c(0,0,1,5,1), ANOTHER=c(4,1,9,2,3))


# list of dataframes

dfs <- list(quality, thickness, distance)


# a very simple function (just for testing)
# actually a very complex one is used on real data

BetterNames <- function(x) {
    names(x) <- tolower(names(x))
  x
}


# apply function to data frame list

dfs <- lapply(dfs, BetterNames)

# I know the expected R behaviour is to modify a copy of the object,
# instead of the original object itself. So if you get the names
# you get the original version, not the needed one

names(quality)

[1] "FIRST"  "SECOND"

有没有办法在循环中使用任何函数或者&#34; apply&#34;适用于大量数据框架? 因此,对于列表中的每个数据框(大列表),我们必须将修改后的版本替换为原始版本

我知道使用数据表有一个技巧,但我想知道是否可以使用基数R。

预期结果:

 names(quality)

    [1] "first"  "second"

[EDITED] 指出这个答案:Rename columns in multiple dataframes, R

但不行。在我的情况下,您不能使用字符串名称向量,因为我的新名称不是固定的字符串列表。[编辑数据]

for(df in dfs) {
  df.tmp <- get(df)
  names(df.tmp) <- BetterNames(df)
  assign(df, df.tmp)
}

> names(quality)
[1] "quality" NA  

由于

3 个答案:

答案 0 :(得分:2)

您已经拥有最佳案例:

我们在列表中添加一些名称:

names(dfs) <- c("quality", "thickness", "distance")
dfs <- lapply(dfs, BetterNames)

dfs[["quality"]]
#   first second
# 1     1      3
# 2     5      6
# 3     3      1
# 4     3      5
# 5     2      5

这很有效。并且您的所有数据都在列表中,因此如果您想对所有数据框执行其他操作,则非常容易。

如果你已经完成了对这些数据框的处理,并且真的希望它们回到全球环境中以便单独使用,你可以用

来完成
list2env(dfs, envir = .GlobalEnv)

我建议将它们保存在列表中---在大多数情况下,如果您使用的是50个数据框,则在list中,它很容易使用lapply或{{1使用它们循环,但作为单个对象,您将复制/粘贴代码并犯错误。

我甚至会考虑在你的工作区中从50个数据框开始出现问题 - 请参阅How do I make a list of data frames?以获取有关查找上游修复的建议:从一开始直接进入列表。

答案 1 :(得分:2)

我使用一个简单但有效的解析&amp;评估方法。

让我们使用for循环来编写符合您需求的命令:

for(df in dfs) {

command <- paste0("names(",df,") <- BetterNames(",df,")")
# print(command)
eval(parse(text=command))

}

names(quality)
[1] "first"  "second"

names(thickness)
[1] "third"  "fourth"

names(distance)
[1] "onemore"  "another"

答案 2 :(得分:0)

这肯定不是最佳的,我希望有更好的东西出现,但在这里:

BetterNames <- function(x, y) {

    names(x) <- tolower(names(x))
    assign(y, x, envir = .GlobalEnv)

}

dfs <- list(quality, thickness, distance)
dfs2 <- c("quality", "thickness", "distance")
mapply(BetterNames, dfs, dfs2)

> names(quality)
[1] "first"  "second"