以使用 mutate、cross 和 case_when 为条件连接一列中的列名

Tar*_*Jae 17 r dplyr across

我想要:

  1. 使用acrosscase_when检查列 A1-A3 == 1
  2. 连接 A1-A3 == 1 和
  3. 使用连接的列名改变新列

我的数据框:

df <- tribble(
~ID,    ~A1,    ~A2,    ~A3,
1, 0, 1, 1, 
2, 0, 1, 1, 
3, 1, 1, 1, 
4, 1, 0, 1, 
5, 0, 1, 0)
Run Code Online (Sandbox Code Playgroud)

期望输出:

# A tibble: 5 x 5
     ID    A1    A2    A3 New_Col 
  <dbl> <dbl> <dbl> <dbl> <chr>   
1     1     0     1     1 A2 A3   
2     2     0     1     1 A2 A3   
3     3     1     1     1 A1 A2 A3
4     4     1     0     1 A1 A3   
5     5     0     1     0 A2   
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经尝试过:

df %>% 
  rowwise() %>% 
  mutate(New_Col = across(A1:A3, ~ case_when(. == 1 ~ paste0("colnames(.)", collapse = " "))))
Run Code Online (Sandbox Code Playgroud)

不工作输出:

     ID    A1    A2    A3 New_Col$A1  $A2         $A3        
  <dbl> <dbl> <dbl> <dbl> <chr>       <chr>       <chr>      
1     1     0     1     1 NA          colnames(.) colnames(.)
2     2     0     1     1 NA          colnames(.) colnames(.)
3     3     1     1     1 colnames(.) colnames(.) colnames(.)
4     4     1     0     1 colnames(.) NA          colnames(.)
5     5     0     1     0 NA          colnames(.) NA   
Run Code Online (Sandbox Code Playgroud)

我想学习的内容:

  1. 是否可以用于across检查多列的条件
  2. 如果是,如何查看 ~ of 之后的部分case_when以获取特定的列名
  3. 我怎样才能使用后得到只有一列mutateacrosscase_when与喜欢这里不是3。

我以为我已经能够掌握这项任务,但不知何故我失去了它......

Ron*_*hah 7

acrosscase_when您一起使用可以 -

library(dplyr)
library(tidyr)

df %>% 
  mutate(across(A1:A3, ~case_when(. == 1 ~ cur_column()), .names = 'new_{col}')) %>%
  unite(New_Col, starts_with('new'), na.rm = TRUE, sep = ' ')

#    ID    A1    A2    A3 New_Col 
#  <dbl> <dbl> <dbl> <dbl> <chr>   
#1     1     0     1     1 A2 A3   
#2     2     0     1     1 A2 A3   
#3     3     1     1     1 A1 A2 A3
#4     4     1     0     1 A1 A3   
#5     5     0     1     0 A2      
Run Code Online (Sandbox Code Playgroud)

across创建3名为新列new_A1new_A2new_A3与列名,如果该值是1或NA以其它方式。使用unite我们将 3 列合并为一列New_col


此外,我们可以使用rowwisec_across-

df %>% 
  rowwise() %>% 
  mutate(New_Col = paste0(names(.[-1])[c_across(A1:A3) == 1], collapse = ' '))
Run Code Online (Sandbox Code Playgroud)


Ani*_*yal 5

没有rowwise/across你也可以使用cur_data()

df %>% group_by(ID) %>%
  mutate(new_col = paste0(names(df[-1])[as.logical(cur_data())], collapse = ' '))

# A tibble: 5 x 5
# Groups:   ID [5]
     ID    A1    A2    A3 new_col 
  <dbl> <dbl> <dbl> <dbl> <chr>   
1     1     0     1     1 A2 A3   
2     2     0     1     1 A2 A3   
3     3     1     1     1 A1 A2 A3
4     4     1     0     1 A1 A3   
5     5     0     1     0 A2 
Run Code Online (Sandbox Code Playgroud)

a.而不是dfinside mutate 也可以

df %>% group_by(ID) %>%
  mutate(new_col = paste0(names(.[-1])[as.logical(cur_data())], collapse = ' '))
Run Code Online (Sandbox Code Playgroud)