我有一个与此类似的数据框:
df <- data.frame(a_1_1 = c(1, 0, 1), a_1_2=c(1,0,0),a_2_1=c(1,0,0), a_2_2=c(1,0 ,1), b=c(2,3,4))
我想通过以下列方式比较具有相同前缀的列来创建新变量:
df <- df %>% mutate(a_1=case_when((a_1_1==1 | a_1_2==1)~"A", TRUE ~ "B")) %>%
mutate(a_2=case_when((a_2_1==1 | a_2_2==1)~"A", TRUE ~ "B"))
但是,在我的真实数据中,我有很多以“ a_ *”开头的变量,因此我想创建这些变量而不必一次对每个变量进行一次操作。
一个选项across
通过循环通过柱,与“a”后跟一个开始_
和一些数字,然后_
并在结束数字1( $
)的字符串,利用case_when
在该列(.
)并将该值返回(get
通过)通过使用更改列名(cur_column()
)将相应的列str_replace
指定为对应的列_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'))
-输出
# a_1_1 a_1_2 a_2_1 a_2_2 b a_1 a_2
#1 1 1 1 1 2 A A
#2 0 0 0 0 3 B B
#3 1 0 0 1 4 A A
或另一种选择是用于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")
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句