R 使用数据帧列表将函数应用于列名

R 使用数据帧列表将函数应用于列名,r,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

我正在尝试将一个非常复杂的函数应用于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"
[已编辑] 针对这一回答,

但不起作用。在我的案例中不能使用字符串名称向量,因为我的新名称不是固定的字符串列表。[已编辑数据]

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

> names(quality)
[1] "quality" NA  
for(dfs中的df){

df.tmp这肯定不是最优的,我希望会有更好的结果,但这里是:

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"

BetterNames您已经有了最佳案例场景:

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

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
但我建议将它们保存在一个列表中——在大多数情况下,如果您有50个正在使用的数据帧,在
列表中使用
lappy
循环使用它们很容易,但作为单个对象,您将复制/粘贴代码并出错



我甚至会考虑从工作区中的50个数据帧开始问题——请参阅关于查找上游修复的建议:从一开始就直接进入列表。

< P>我将使用一个简单但有效的解析和EVE方法。

让我们使用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"
for(dfs中的df){

命令您是否检查了名称(dfs[[1]]),因为您正在参考质量,即名称在BetterNames之前的dataframe。M.Siwik,如果可能的话,问题是修改所有数据帧名称。想象一下我们是否必须使用名称(dataframe)嗨!我想您正在寻找的答案在这里:(参见第二个答案!)检查这个答案。因为你必须将你的df保存在列表中,以便只执行一个命令,并且具有很好的矢量化计算速度。简单的答案是不要在全局环境中处理50个单独的对象。你已经有了一个
列表,你应该使用它。如果你需要一个命名列表来简化操作,请尝试-
m获取(c(“质量”、“厚度”、“距离”)
来创建它。我认为对结果使用
list2env
是不好的,但仍然比让函数进行全局赋值要好。使用OP的
BetterNames
dfs=lappy(dfs,BetterNames);name(dfs)=c(“质量”、“厚度”、“距离”);list2env(dfs,envir=.GlobalEnv)
是的,你是对的,我真的没有找到一个“好”的解决方案来解决这个问题。(顺便说一句,我不知道list2env函数,谢谢你!)你的答案更好!请创建一个新的答案或添加它,以便OP可以看到它!简单明了!非常有效。谢谢
list2env(dfs, envir = .GlobalEnv)
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"