通过在 dplyr 中过滤其他列来改变一列

Mutate one column by filtering others in dplyr

我有一个包含多个互斥列的数据集。其中一列包含该观察结果的答案(例如“abc”),而其余列包含代表 NA 的负数。正如下面玩具数据集中的 A 列,一列总是包含相同的答案。

我想通过将列与每个观察的答案合并来创建一个新变量。到目前为止,我是按照下面的方式进行的,但在真实数据集中有 50 列用于 2000 次观察,所以我正在寻找一种更优化(也更优雅)的方法来做到这一点。

data <- tibble::tribble(
  ~id, ~A, ~B, ~C,
  "a", "ES01", "-1", "-2",
  "b", "-1","-3", "CH041",
  "c", "-2", "DDE24", "-1",
  "d", "ES01", "-3", "-1"
)

data %>% 
  dplyr::mutate(across(A:C, ~ ifelse(str_starts(.,"-"), "", .))) %>%
  dplyr::mutate(regions = paste0(A, B, C))

谢谢。

您可以使用 tidyr::pivot_longer 将数据转换为长格式,然后再使用 filter

data %>%
  pivot_longer(-id, names_to = "col", values_to = "answer") %>%
  filter(!grepl("\d", answer))

# A tibble: 4 x 3
  id    col   answer
  <chr> <chr> <chr> 
1 a     A     abc   
2 b     C     def   
3 c     B     ghi   
4 d     A     abc  

我们可以使用tidyr中的unite,然后用str_remove_all

去掉数字/-字符
library(dplyr)
library(tidyr)
library(stringr)
data %>%
  unite(regions, A:C, remove = FALSE) %>%
  mutate(regions = str_remove_all(regions, "[^a-z]+"))

-输出

# A tibble: 4 × 5
  id    regions A     B     C    
  <chr> <chr>   <chr> <chr> <chr>
1 a     abc     abc   -1    -2   
2 b     def     -1    -3    def  
3 c     ghi     -2    ghi   -1   
4 d     abc     abc   -3    -1   

使用更新后的数据集

data %>%
   unite(regions, A:C, remove = FALSE) %>% 
   mutate(regions = str_remove_all(regions, "_?-[0-9]+_?"))

-输出

# A tibble: 4 × 5
  id    regions A     B     C    
  <chr> <chr>   <chr> <chr> <chr>
1 a     ES01    ES01  -1    -2   
2 b     CH041   -1    -3    CH041
3 c     DDE24   -2    DDE24 -1   
4 d     ES01    ES01  -3    -1