问题描述
如果之前有人问过这个问题,我们深表歉意。这是我对 R 的理解的极限,所以我什至不确定用什么正确的语言来表达查询(因此,我无法识别重复的问题)。
在我的环境中,我有未知数量的对象(数据帧),每个对象都有未知数量的列,这些列的名称有意义但结尾无意义,因此很难引用它们。列名称的有意义部分通常后跟双句点和一些其他文本。我想自动查找和删除无意义的后缀。我想修改的所有对象的名称中都有“.dat”。这是我尝试的示例:
# create some objects in my environment
a <- "a string,not of interest to me"
b.dat <- data.frame(col1 = 1:2,col2..gibberish = 3:4)
c.dat <- data.frame(col1..some.text = 5:6,col2 = 7:8)
# find the dataframes that I want to manipulate
dfs <- ls(pattern = ".dat")
# loop through the objects in question,finding and changing the problematic column names
colrename <- lapply(dfs,function(df){
# get the relevant dataframe
dat <- get(df)
# find its column names
nms <- names(dat)
# find the column names with the problematic ".." suffixes
problem.cols <- grep("\\.\\.",nms)
# pull out the meaningful first parts of each problematic name
parts <- strsplit(nms[problem.cols],"\\.\\.")
parts <- sapply(parts,function(x) x[1])
# and,the bit that doesn't work: change the problematic column names to their shorter alternatives
names(get(df))[problem.cols] <<- parts
return(0)
})
如果我一行一行地运行,它会做我想做的一切,直到并包括 names(get(df))[problem.cols],它知道这是列的名称在我试图改变的数据框中。但是,它不会将更改的名称分配给它,从而产生错误消息:Error in get(*tmP*
) : invalid first argument。
我愿意采用其他方法来实现我想要的终点。但是,我也对为什么这不起作用以及如何更一般地更改使用“get()”引用的对象很感兴趣。提前感谢您的任何建议 - 如果这太天真了,只是阅读它是在浪费您的时间,我们深表歉意。
FWIW,我可以看到与 this question 的相似之处,但我无法根据我的需要调整答案。
解决方法
实际上,我最终制作了使用“分配”功能的链接。这似乎有效(所以我已将其发布在这里,以防对其他人有所帮助)-但我仍然对替代解决方案感兴趣:
# loop through the objects in question,finding and changing the problematic column names
colrename <- lapply(dfs,function(df){
# get the relevant dataframe
dat <- get(df)
# find its column names
nms <- names(dat)
# find the column names with the problematic ".." suffixes
problem.cols <- grep("\\.\\.",nms)
# pull out the meaningful first parts of each problematic name
parts <- strsplit(nms[problem.cols],"\\.\\.")
parts <- sapply(parts,function(x) x[1])
# change the problematic column names to their shorter alternatives
nms[problem.cols] <- parts
names(dat) <- nms
assign(df,dat,envir = .GlobalEnv)
return(0)
})