重命名列名,考虑到非连续的列名编号。

3

我有这样的数据:

library(tidyverse)
dat <- cars %>%
  t() %>%
  as_tibble()
dat <- dat %>%
  rename(dummy = V10)
dat

# A tibble: 2 × 50
     V1    V2    V3    V4    V5    V6    V7    V8    V9 dummy   V11   V12   V13
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     4     4     7     7     8     9    10    10    10    11    11    12    12
2     2    10     4    22    16    10    18    26    34    17    28    14    20
# … with 37 more variables: V14 <dbl>, V15 <dbl>, V16 <dbl>, V17 <dbl>, V18 <dbl>,
#   V19 <dbl>, V20 <dbl>, V21 <dbl>, V22 <dbl>, V23 <dbl>, V24 <dbl>, V25 <dbl>,
#   V26 <dbl>, V27 <dbl>, V28 <dbl>, V29 <dbl>, V30 <dbl>, V31 <dbl>, V32 <dbl>,
#   V33 <dbl>, V34 <dbl>, V35 <dbl>, V36 <dbl>, V37 <dbl>, V38 <dbl>, V39 <dbl>,
#   V40 <dbl>, V41 <dbl>, V42 <dbl>, V43 <dbl>, V44 <dbl>, V45 <dbl>, V46 <dbl>,
#   V47 <dbl>, V48 <dbl>, V49 <dbl>, V50 <dbl>
# ℹ Use `colnames()` to see all variable names

我希望列名为"V8,V9,dummy,V10V11..."。如何通过操作列名来实现这个目标?我想知道是否可以使用dplyr :: rename_with 来完成这个任务,但我不确定该如何编写代码。

如果有任何帮助将不胜感激,谢谢您提前帮忙。

编辑:我想知道是否有一种方法可以在指定要重命名的列时不依赖于列数(例如dat [10:49]),因为实际数据更大,并且我必须对多个系列的项目执行此操作。感谢Jon Spring指出这一点。

4个回答

4

使用regmatches及其替换模式:

rg <- regexpr("\\d+", names(dat))
regmatches(names(dat), rg) <- seq_along(rg)
dat
## A tibble: 2 × 50
#     V1    V2    V3    V4    V5    V6    V7    V8    V9 dummy   V10   V11   V12
#  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#...

2
dat_names <- names(dat)
names(dat) = c(dat_names[1:9], "dummy", dat_names[10:49])

或者如果您不知道要替换的列位于哪个位置,但您知道它的名称:

dat_names <- names(dat)
col <- match("V10", dat_names)
names(dat) = c(dat_names[1:(col-1)], "dummy", 
               dat_names[(col+1):length(dat_names)])

谢谢!虽然我想找到一种不依赖于列号来指定要重命名的列的解决方案,因为实际数据比示例数据大得多。编辑了问题以澄清这一点。 - r_noobie
你知道要插入的列名的哪些信息吗?例如,你想用它替换当前名为V10的列吗?或者它是跟在V9后面的?但你不知道它是第10列? - Jon Spring
我想要在不打破列号顺序的情况下“插入”“虚拟”变量。例如)我有V1,V2,V3 ... V10,并且我想插入“虚拟”而不是像V1 ... V5,dummy,V7,V8 ... V10这样。因此,理想情况下,我不想依赖手动指定后续列号,因为它应该根据已经存在的序列进行指定,但如果必要的话,我可以手动完成。 - r_noobie
那么我认为第二种解决方案符合您的要求?在这种情况下,“V10”是我们知道应该变成“dummy”的名称。 - Jon Spring

2

这应该与数字无关,但它取决于您想用“dummy”重命名的列名:此解决方案使用rename_withappendmatch函数。基本上,我们使用match获取“V9”的索引,然后在此索引之后将其附加到colnames向量中:

library(dplyr)
cars %>%
  t() %>%
  as_tibble() %>% 
  rename_with(., ~append(colnames(dat), "dummy", after = match("V9", colnames(dat))))

 [1] "V1"    "V2"    "V3"    "V4"    "V5"    "V6"    "V7"    "V8"    "V9"    "dummy" "V10"   "V11"   "V12"   "V13"   "V14"   "V15"  
[17] "V16"   "V17"   "V18"   "V19"   "V20"   "V21"   "V22"   "V23"   "V24"   "V25"   "V26"   "V27"   "V28"   "V29"   "V30"   "V31"  
[33] "V32"   "V33"   "V34"   "V35"   "V36"   "V37"   "V38"   "V39"   "V40"   "V41"   "V42"   "V43"   "V44"   "V45"   "V46"   "V47"  
[49] "V48"   "V49"  

0
经过数小时的摸索和社区的帮助,我终于成功运用以下方法让它正常工作:
res <- dat %>%
  rename_with(str_replace,
              pattern = "\\d+", replacement = function(x)
                (x %>%
                   str_subset("\\d+") %>%
                   as.numeric() - 1 %>%
                   return()),
              num_range("V", 10:50))
res %>%
  names()

 [1] "V1"    "V2"    "V3"    "V4"    "V5"    "V6"    "V7"    "V8"    "V9"    "dummy" "V10"   "V11"  
[13] "V12"   "V13"   "V14"   "V15"   "V16"   "V17"   "V18"   "V19"   "V20"   "V21"   "V22"   "V23"  
[25] "V24"   "V25"   "V26"   "V27"   "V28"   "V29"   "V30"   "V31"   "V32"   "V33"   "V34"   "V35"  
[37] "V36"   "V37"   "V38"   "V39"   "V40"   "V41"   "V42"   "V43"   "V44"   "V45"   "V46"   "V47"  
[49] "V48"   "V49" 

非常感谢您的帮助!

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