【问题标题】:dplyr mutate based on other column with different suffixdplyr 基于具有不同后缀的其他列进行变异
【发布时间】:2021-06-07 21:18:21
【问题描述】:

我有一个类似的数据框:

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_*”开头的变量,所以我想创建这些变量,而不是为每个变量一次做一次。

【问题讨论】:

    标签: r dplyr prefix suffix


    【解决方案1】:

    across 的选项通过循环遍历以 'a' 开头的列,然后是 _ 和一些数字,然后是 _ 和字符串末尾的数字 1 ($),在该列 (.) 上使用 case_when,并通过将列名称 (cur_column()) 更改为 str_replace,将相应列返回的值 (get) 指定为新列的后缀为 @ 987654330@,然后在下一步中将这些列重命名为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 Rsplit.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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-13
      • 2021-07-29
      • 1970-01-01
      • 1970-01-01
      • 2018-08-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多