R - 使用get()更改列名

时间:2017-12-07 15:23:30

标签: r get

我在全球环境中有几个data.frame我需要合并。许多data.frame具有相同的列名。我想在每个标记其原始data.frame的列上附加后缀。因为我有很多data.frame,所以我希望自动化该过程,如下例所示。

df1 <-  data.frame(id = 1:5,x = LETTERS[1:5])
df2 <-  data.frame(id = 1:5,x = LETTERS[6:10])

obj <- ls()

for(o in obj){
  s <- sub('df','',eval(o))
  names(get(o))[-1] <- paste0(names(get(o))[-1],'.',s)
}

# Error in get(o) <- `*vtmp*` : could not find function "get<-"'

但是作业的各个部分都可以正常工作:

names(get(o))[-1]
# [1] "x"
paste0(names(get(o))[-1],'.',s)
# [1] "x.1"

我使用get以类似的方式将每个对象write.csv添加到文件中。

for(o in obj){
  write.csv(get(o),file = paste0(o,'.csv'),row.names = F)
}

为什么它不能在作业中更改列名?

3 个答案:

答案 0 :(得分:1)

错误&#34;找不到函数get<-&#34;是R告诉你,你不能使用<-更新&#34;得到&#34;宾语。您可以使用assign,但此代码已经足够难以阅读。更好的解决方案是使用list

从你的例子:

df1 <-  data.frame(id = 1:5,x = LETTERS[1:5])
df2 <-  data.frame(id = 1:5,x = LETTERS[6:10])

# put your data frames in a list
df_names = ls(pattern = "df[0-9]+")
df_names   # make sure this is the objects you want
# [1] "df1" "df2"
df_list = mget(df_names)

# now we can use a simple for loop (or lapply, mapply, etc.)
for(i in seq_along(df_list)) {
    names(df_list[[i]])[-1] =
        paste(names(df_list[[i]])[-1],
              sub('df', '', names(df_list)[i]),
              sep = "."
        )
}

# and the column names of the data frames in the list have been updated
df_list
# $df1
#   id x.1
# 1  1   A
# 2  2   B
# 3  3   C
# 4  4   D
# 5  5   E
# 
# $df2
#   id x.2
# 1  1   F
# 2  2   G
# 3  3   H
# 4  4   I
# 5  5   J

现在也很容易合并它们:

Reduce(f = merge, x = df_list)
#   id x.1 x.2
# 1  1   A   F
# 2  2   B   G
# 3  3   C   H
# 4  4   D   I
# 5  5   E   J

有关更多讨论和示例,请参阅How do I make a list of data frames?

答案 1 :(得分:0)

您可以使用eval来评估指定环境中的R表达式。

df1 <- data.frame(id = 1:5,x = LETTERS[1:5])
df2 <- data.frame(id = 1:5,x = LETTERS[6:10])

obj <- ls()

for(o in obj) {
  s <- sub('df', '', o)
  new_name <- paste0(names(get(o))[-1], '.', s)
  eval(parse(text = paste0('names(', o, ')[-1] <- ', substitute(new_name))))
}

修改df1和df2

  id x.1
1  1   A
2  2   B
3  3   C
4  4   D
5  5   E

答案 2 :(得分:0)

您可以使用setnames中的library(data.table)

for(o in obj) {
  oldnames = names(get(o))[-1]
  newnames = paste0(oldnames, ".new")
  setnames(get(o), oldnames, newnames)
}