使用 R 中的正则表达式匹配将一列替换为另一列
replace one column with another using regex matching in R
我正在处理一些调查数据,我想用另一个调查项目替换一个调查 item/column 的内容,同时保留原始单元格内容。例如 - 如果缺少 Q2_1.x,则将 Q2_1.x 替换为 Q2_1.y。
这是我的数据示例:
org_dat <- read_table('ID Q2_1.x Q2_2.x Q2_1.y Q2_2.y Q14_1.x Q14_1.y Q15
1 Yes NA NA NA Sometimes NA NA
2 -99 NA No NA NA Always Yes
3 NA NA NA NA NA NA NA
4 NA NA NA No NA NA No
5 NA NA NA NA NA Always NA
6 NA NA NA No NA NA NA') %>% mutate_all(as.character)
这是我想要的输出:
dat_out <- read_table('ID Q2_1 Q2_2 Q14_1 Q15
1 Yes NA Sometimes NA
2 No NA Always Yes
3 NA NA NA NA
4 NA No NA No
5 NA NA Always NA
6 NA No NA NA')
当前解
我知道我可以单独替换这些列中的每一列,但我有很多列要处理,我想使用一种聪明的 dplyr/grepl 方法来解决这个问题!有任何想法吗?我总是用 Q*.y 替换 Q*.x。
org_dat %>% mutate(Q2_1.x = case_when(is.na(Q2_1.x) ~ Q2_1.y,
TRUE ~ Q2_1.x)) %>%
mutate(Q2_2.x = case_when(is.na(Q2_2.x) ~ Q2_2.y,
TRUE ~ Q2_2.x)) %>%
mutate(Q14_1.x = case_when(is.na(Q14_1.x) ~ Q14_1.y,
TRUE ~ Q14_1.x)) %>%
rename(Q2_1 = Q2_1.x,
Q2_2 = Q2_2.x,
Q14_1 = Q14_1.x) %>%
select(-matches("x|y"))
这是一个带有 across
和 coalesce
的选项,循环 across
ends_with
'x' 的列,替换 (str_replace
)列名 (cur_column()
) 中的子字符串从 'x' 到 'y',get
列值,对循环列执行 coalesce
,然后删除.names
中列名的子字符串
library(dplyr)
library(stringr)
org_dat %>%
mutate(across(ends_with("x"),
~ coalesce(., get(str_replace(cur_column(), "x", "y"))),
.names = "{str_remove(.col, '.x')}"), .keep = "unused", .before = 2)
-输出
# A tibble: 6 × 5
ID Q2_1 Q2_2 Q14_1 Q15
<chr> <chr> <chr> <chr> <chr>
1 1 Yes <NA> Sometimes <NA>
2 2 No <NA> Always Yes
3 3 <NA> <NA> <NA> <NA>
4 4 <NA> No <NA> No
5 5 <NA> <NA> Always <NA>
6 6 <NA> No <NA> <NA>
我正在处理一些调查数据,我想用另一个调查项目替换一个调查 item/column 的内容,同时保留原始单元格内容。例如 - 如果缺少 Q2_1.x,则将 Q2_1.x 替换为 Q2_1.y。
这是我的数据示例:
org_dat <- read_table('ID Q2_1.x Q2_2.x Q2_1.y Q2_2.y Q14_1.x Q14_1.y Q15
1 Yes NA NA NA Sometimes NA NA
2 -99 NA No NA NA Always Yes
3 NA NA NA NA NA NA NA
4 NA NA NA No NA NA No
5 NA NA NA NA NA Always NA
6 NA NA NA No NA NA NA') %>% mutate_all(as.character)
这是我想要的输出:
dat_out <- read_table('ID Q2_1 Q2_2 Q14_1 Q15
1 Yes NA Sometimes NA
2 No NA Always Yes
3 NA NA NA NA
4 NA No NA No
5 NA NA Always NA
6 NA No NA NA')
当前解 我知道我可以单独替换这些列中的每一列,但我有很多列要处理,我想使用一种聪明的 dplyr/grepl 方法来解决这个问题!有任何想法吗?我总是用 Q*.y 替换 Q*.x。
org_dat %>% mutate(Q2_1.x = case_when(is.na(Q2_1.x) ~ Q2_1.y,
TRUE ~ Q2_1.x)) %>%
mutate(Q2_2.x = case_when(is.na(Q2_2.x) ~ Q2_2.y,
TRUE ~ Q2_2.x)) %>%
mutate(Q14_1.x = case_when(is.na(Q14_1.x) ~ Q14_1.y,
TRUE ~ Q14_1.x)) %>%
rename(Q2_1 = Q2_1.x,
Q2_2 = Q2_2.x,
Q14_1 = Q14_1.x) %>%
select(-matches("x|y"))
这是一个带有 across
和 coalesce
的选项,循环 across
ends_with
'x' 的列,替换 (str_replace
)列名 (cur_column()
) 中的子字符串从 'x' 到 'y',get
列值,对循环列执行 coalesce
,然后删除.names
library(dplyr)
library(stringr)
org_dat %>%
mutate(across(ends_with("x"),
~ coalesce(., get(str_replace(cur_column(), "x", "y"))),
.names = "{str_remove(.col, '.x')}"), .keep = "unused", .before = 2)
-输出
# A tibble: 6 × 5
ID Q2_1 Q2_2 Q14_1 Q15
<chr> <chr> <chr> <chr> <chr>
1 1 Yes <NA> Sometimes <NA>
2 2 No <NA> Always Yes
3 3 <NA> <NA> <NA> <NA>
4 4 <NA> No <NA> No
5 5 <NA> <NA> Always <NA>
6 6 <NA> No <NA> <NA>