在 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))]
}
在数据框中,我想在名称与特定模式匹配的每一列旁边添加一个新列,例如,其名称以“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))]
}