如何在R中根据另一个数据框更改列名?

7
df1 <- data.frame(
    cola = c('1',NA,'c','1','1','e','1',NA,'c','d'),
    colb = c("A",NA,"C","D",'a','b','c','d','c','d'),
    colc = c('a',NA,'c','d','a',NA,'c',NA,'c','d'),stringsAsFactors = TRUE)

df2<-data.frame(name=c('cola','colc','colb'),
                altname=c('a','c','b'))

df1 %>% table %>% data.frame(.)

上述代码的结果如下:
   cola colb colc Freq
1     1    a    a    1
2     c    a    a    0

我想根据df2更改结果的列名(例如,将colb更改为b),预期结果如下:
      a    b    c Freq
1     1    a    a    1
2     c    a    a    0

如何做到?

2个回答

5
我们可以使用rename_at来删除子字符串。
library(stringr)
libraryr(dplyr)
df1 %>% 
   table %>% 
   data.frame(.) %>%  
   rename_at(1:3, ~ str_remove(., "col"))

或者如果需要从'df2'中获取

df1 %>%
   table %>%
   data.frame(.) %>%
   rename_at(1:3, ~ setNames(as.character(df2$altname), df2$name)[.])

更新

如果“df1”中的所有列名都不在“df2”的键/值列中,则有一个选项:

df1 %>%
   table %>%
    data.frame(.) %>%
    rename_at(1:3, ~ coalesce(setNames(as.character(df2$altname), df2$name)[.], .)) 

或者使用基础的 R

out <- df1 %>% table %>% data.frame(.)
names(out) <- sub("col", "", names(out))

如果需要基于第二个数据集进行操作。
name(out)[-4] <- df2$altname[match(names(out)[-4], df2$name)]

或者使用substr函数。
names(out) <- substring(names(out), 4)

逻辑:更改df1的每个列名,如果在df2中存在相应的列名,则进行更改。 - kittygirl
如果在df2中没有相应的匹配,那么输出应该是什么? - akrun
如果没有对应的内容,请不做任何更改并输出相同的列名。 - kittygirl
我尝试了 df1 %>% table %>% data.frame(.) %>% \colnames<-`(df2$altname[match(names(df1), df2$name)]),唯一不满意的是 Freq没有匹配,变成了NA`。是否有办法在没有匹配时保持相同的列名? - kittygirl
@kittygirl。我使用了 coalesce。虽然它对我有用,但在这里我正在使用 rename_at 通过删除 Freq 列来实现。 - akrun

0

当我在研究同样的问题时,这是我着陆的较受欢迎的线程之一。如果您使用命名向量并利用any_of函数,dplyr的更近期的版本可以更轻松地解决此问题,这使得它在您具有可能在df2中但不在df1中的列名时变得相当容易。

使用您的情况,您可以:

lookup <- setNames(as.character(df2$name), df2$altname)
df1 %>% 
  rename(any_of(lookup)) %>% 
  table %>% 
  data.frame(.)

或者作为一个嵌入式的一行代码:

df1 %>% 
  rename(any_of(setNames(as.character(df2$name), df2$altname))) %>% 
  table %>% 
  data.frame(.)

或者,如果您想避免使用 setNames 过程,那么在 tibble 中有一个很好的 deframe 函数,它将数据框的前两列转换为命名向量(并忽略其余部分),但是您在 df2 中的列顺序会颠倒(旧名称、新名称)。

参考资料:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接