通过循环遍历以字母'a'开头,后面跟着一个下划线和一些数字,然后是下划线和数字1的列,使用case_when
函数对该列(.
)和相应列返回的值 (get
) 进行操作,通过使用str_replace
更改列名(cur_column()
)并指定新列的后缀为_new
,然后在下一步中使用rename_with
重命名这些列。
library(dplyr)
library(stringr)
df %>%
mutate(across(matches('^a_\\d+_1$'),
~ case_when(. == 1| get(str_replace(cur_column(), '_\\d+$', '_2')) == 1 ~ 'A',
TRUE ~ 'B'), .names = '{.col}_new')) %>%
rename_with(~ str_remove(., '_\\d+_new'), ends_with('new'))
-输出
另一个选项是使用 pivot_longer
将数据转换为“长”格式,使得比较和创建新列变得更加容易,然后再使用 pivot_wider
将数据转换回宽格式,并将这些新列绑定到原始数据。
library(tidyr)
df
select(-b)
mutate(rn = row_number())
pivot_longer(cols = -rn, names_to = c('grp', '.value'),
names_sep = "_(?=\\d+$)")
transmute(rn, grp, val = case_when(`1` == 1|`2` == 1 ~ 'A',
TRUE ~ 'B'))
pivot_wider(names_from = grp, values_from = val)
select(-rn)
bind_cols(df, .)
或者使用 base R
和 split.default
df[paste0("a_", 1:2)] <- ifelse(
sapply(split.default(df[startsWith(names(df), "a_")],
sub("_\\d+$", "", grep("^a_", names(df), value = TRUE))),
rowSums) > 0, 'A', 'B')
或者使用for
循环
nm1 <- unique(sub("_\\d+$", "", grep('^a_\\d+', names(df), value = TRUE)))
for(nm in nm1) df[[nm]] <- ifelse(rowSums(df[startsWith(names(df),
nm)]) > 0, "A", "B")