创建指示符变量以检测R中以word开头的任何列中的字符串

4c8rllxm  于 2023-05-04  发布在  其他
关注(0)|答案(1)|浏览(135)

我有一个包含许多列的数据集。我对变量名中包含“dx_”的列感兴趣。我想创建一个指示符变量,在每行中至少有一个列的名称包含“dx_”,其值以“493”开头。例如:

df = data.frame(var1 = c(1,2,3,4,5),var2 = c(5,4,3,2,1),dx_1 = c("493","XH","1493","4938B","LP23"),dx_2 = c("AB","0PC3","MNP","12GT","FPN2"),a_dx_3 = c("FTR","2RTN","92KS","J294","493V"))

> df
  var1 var2  dx_1 dx_2 a_dx_3
1    1    5   493   AB    FTR
2    2    4    XH 0PC3   2RTN
3    3    3  1493  MNP   92KS
4    4    2 4938B 12GT   J294
5    5    1  LP23 FPN2   493V

我想创建一个新变量Z,如果dx_1dx_2a_dx_3中的任何一个在该行中的值以“493”开头,则该变量为1,否则为0。但是,我需要灵活的解决方案,这样我就不必指定哪些列,而只需要说contains("dx_")
我希望我的答案看起来像这样:

var1 var2  dx_1 dx_2 a_dx_3 Z
1    1    5   493   AB    FTR 1
2    2    4    XH 0PC3   2RTN 0
3    3    3  1493  MNP   92KS 0
4    4    2 4938B 12GT   J294 1
5    5    1  LP23 FPN2   493V 1

这是我失败的尝试:首先,我创建一个helper函数来识别字符串:

detect_493_fn <- function(str){
  ans = if_else(str_starts(str,"493") == TRUE,
                1,
                0)
  return(ans)
}

然后使用if_any、across和contains的组合:

ans <- df %>%
  mutate(Z = case_when(
    if_any(across(contains("dx_"), ~detect_493_fn(.))) ~ 1,
    TRUE ~ 0))

但我得到了这个错误:

Error in `mutate()`:
! Problem while computing `Z = case_when(...)`.
Caused by error in `if_any()`:
! Must subset columns with a valid subscript vector.
x Subscript has the wrong type `tbl_df<
  dx_1  : double
  dx_2  : double
  a_dx_3: double
>`.
i It must be numeric or character.

如果有人能帮助我,我将不胜感激。谢谢!

1tu0hz3e

1tu0hz3e1#

您可以:

library(dplyr)
library(stringr)

df %>%
  mutate(Z = as.numeric(if_any(contains("dx"), str_starts, "493")))

  var1 var2  dx_1 dx_2 a_dx_3 Z
1    1    5   493   AB    FTR 1
2    2    4    XH 0PC3   2RTN 0
3    3    3  1493  MNP   92KS 0
4    4    2 4938B 12GT   J294 1
5    5    1  LP23 FPN2   493V 1

考虑将Z变量保持为逻辑变量。if_any()是一个across()变体,因此您可以使用它来代替across(),而不是与它一起使用。

相关问题