无法使用 dplyr rename() 和 rename_with() 重命名重复的列名

Failure to rename duplicate column names with dplyr rename() and rename_with()

给定一个 tibble 或 data.frame 具有重复的列名,我想使用 dplyr::renamedplyr::rename_with 来:
(a) 用序列数字后缀('a_1''a_2' 等)或
区分重复名称 (b) 完全重命名每一列。

有:

library(tidyverse)

d <- tibble(a = 1:3, a = letters[1:3], .name_repair = "minimal")

d
# A tibble: 3 x 2
      a a    
  <int> <chr>
1     1 a    
2     2 b    
3     3 c  

想要:

tibble(a_1 = 1:3, a_2 = letters[1:3])

# A tibble: 3 x 2
    a_1 a_2           # or even just: x, y    
  <int> <chr>
1     1 a    
2     2 b    
3     3 c   

rename/rename_with 可以执行此操作似乎是合理的,特别是因为 colnames(d) <- c("a_1", "a_2") 看起来很明显且不复杂。

但我遇到了不同的错误 and/or 迄今为止我尝试过的三种方法出现意外行为:

1.使用rename(),一列重命名,另一列不重命名:

d %>% rename(x = "a", y = "a")  

# A tibble: 3 x 2
        y a    
    <int> <chr>
  1     1 a    
  2     2 b    
  3     3 c   

2。使用rename_with(),其中我使用函数添加数字后缀,我得到这个错误:

d %>% rename_with(~paste(.x, 1:2, sep = "_"))

Error: Names must be unique.
x These names are duplicated:
  * "a" at locations 1 and 2.

请注意,当数据没有重复的列名时,rename_with 的这种用法按预期工作:

no_dupe <- tibble(a = 1:3, b = letters[1:3])
no_dupe %>% rename_with(~paste(.x, 1:2, sep = "_"))

# A tibble: 3 x 2
    a_1 b_2  
  <int> <chr>
1     1 a    
2     2 b    
3     3 c    

3。使用较旧的 rename_all(),我得到一个不同的错误:

d %>% rename_all(paste0, 1:2)

Error: Can't rename duplicate variables to `{name}`.

我在 the tidyselect GitHub issues 中找到了关于使用 rename 处理重复项的讨论,但那是关于如果用户 创建 重复列名时该怎么办rename(),而不是如果他们试图取消重复该怎么办。

我是不是缺少语法,还是 dplyr::rename 系列没有设置为接收重复的别名?

(我也想更好地理解为什么 rename 只重命名上面示例中的一列,但这功能较少,更多的只是我好奇。)

提前致谢。

假设你有多列有重复甚至三次列名你也可以试试这个方法..

使用 colnames 获取名为 v 的向量中的所有列名称。此后,按照这个方法..

v <- c("a", "a", "b", "c", "c", "c", "d", "e")

df <- tibble(v)


df <- df %>% mutate(id = 1) %>% 
  group_by(v) %>% 
  summarise(id = cumsum(id)) %>% 
  mutate(v2 = paste(v,id, sep = "_")) %>%
  mutate(v2 = ifelse(id==1, v, v2)) 

最后用 df$v2

替换列名
> df$v2
[1] "a"   "a_2" "b"   "c"   "c_2" "c_3" "d"   "e" 

rename 不知道之前的改名。例如,

library(dplyr)
mtcars %>% rename(a = mpg, b = a)

Error: Can't rename columns that don't exist. x Column a doesn't exist.

所以这个

d %>% rename(x = "a", y = "a")  

将同一 a 列重命名两次,首先是 x,然后是 y。另一种方法是打破管道并重命名。

d %>% rename(x = "a") %>% rename(y = "a")  

# A tibble: 3 x 2
#      x y    
#  <int> <chr>
#1     1 a    
#2     2 b    
#3     3 c 
由于 https://github.com/tidyverse/dplyr/blob/master/R/rename.R#L70

rename_with 不允许使用重复的列重命名 dataframe/tibbles。在这种情况下,我认为你最好的选择是使用基础 R 方法。

试试这个:

new_names <- c('a_1', 'a_2')
names(d) <- make.unique(dput(names(d)))
d %>% 
  rename_with(~new_names)
  # rename_at(vars(names(d)), ~new_names)

输出:

    a_1 a_2  
  <int> <chr>
1     1 a    
2     2 b    
3     3 c