R 使用数据帧列表将函数应用于列名
我正在尝试将一个非常复杂的函数应用于50多个数据帧的列表。 为了清晰起见,让我们使用一个非常简单的函数来小写名称和3个数据帧,但我的一般方法如下所示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
[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"