在 R / tidyverse 中与特定列名称模式匹配的每个现有列旁边添加一个新列

Adding a new column next to each existing column that matches a certain column name pattern in R / tidyverse

在数据框中,我想在名称与特定模式匹配的每一列旁边添加一个新列,例如,其名称以“ip_”开头,后跟一个数字。新列的名称应再次遵循以该数字为后缀的模式“newCol_”。新列的值应该是 NA。

所以这个数据框:

应转换为该数据框:

非常感谢使用正则表达式的多样化解决方案!

示例数据:

df <- data.frame(
  ID = c("1", "2"),
  ip_1 = c(2,3),
  ip_9 = c(5,7),
  ip_39 = c(11,13),
  in_1 = c("B", "D"),
  in_2 = c("A", "H"),
  in_3 = c("D", "A")
)

使用 across -

可以轻松获取列
library(dplyr)

df %>%
  mutate(across(starts_with('ip'), ~NA, .names = '{sub("ip", "newCol", .col)}'))

#  ID ip_1 ip_9 ip_39 in_1 in_2 in_3 newCol_1 newCol_9 newCol_39
#1  1    2    5    11    B    A    D       NA       NA        NA
#2  2    3    7    13    D    H    A       NA       NA        NA

按要求的顺序获取列 -

library(dplyr)

df %>%
  mutate(across(starts_with('ip'), ~NA, .names = '{sub("ip", "newCol", .col)}')) %>%
  select(ID, starts_with('in'), 
        order(suppressWarnings(readr::parse_number(names(.))))) %>%
  select(ID, ip_1:newCol_39, everything())

#  ID ip_1 newCol_1 ip_9 newCol_9 ip_39 newCol_39 in_1 in_2 in_3
#1  1    2       NA    5       NA    11        NA    B    A    D
#2  2    3       NA    7       NA    13        NA    D    H    A

要添加新的 NA 列:

df[, sub("^ip", "newCol", grep("^ip", names(df), value = TRUE))] <- NA

重新排序:

df <- df[, order(c(grep("newCol", names(df), invert = TRUE), grep("^ip", names(df))))]

编辑:

如果您(或在这里偶然发现的任何人)计划经常这样做,您可以使用此功能:

insertCol <- function(x, ind, col.names = ncol(df) + seq_along(colIndex), data = NA){
  out <- x
  out[, col.names] <- data
  out[, order(c(col(x)[1,], ind))]
}