R - 如果向量中的任何字符串出现在多列

时间:2016-03-11 09:38:51

标签: r string dataframe apply grepl

我有一个大型数据框,每行都指的是入院。每次入院都附有第5至24栏中最多20个诊断代码。

Col1   Col2   Col3   Col4   Diag_1  Diag_2  Diag_3 ... Diag_20
data   data   data   data   J123    F456    H789       E468
data   data   data   data   T452    NA      NA         NA

另外,我有一个长度为136的向量( risk_codes ),所有字符串。这些字符串是风险代码,可以类似于截断的诊断代码(例如,J12可以,F4可以,H798不会)。

如果任何风险代码与任何诊断代码相似,我希望在数据框中添加一列返回1。我不需要知道多少,只有至少一个是。

到目前为止,我已经尝试了以下方面,但最成功的是其他尝试:

for (in in 1:length(risk_codes){
    df$newcol <- apply(df,1,function(x) sum(grepl(risk_codes[i], x[c(5:24)])))
}

它适用于单个字符串并填充列为0表示没有相似的代码,1表示类似的代码,但是当检查第二个代码时,所有内容都会被覆盖,依此类推到risk_codes向量的136个元素

请问任何想法?对每一行的每一列中的每个risk_code运行一个循环是不可行的。

解决方案看起来像这样

Col1   Col2   Col3   Col4   Diag_1  Diag_2  Diag_3 ... Diag_20   newcol
data   data   data   data   J123    F456    H789       E468      1
data   data   data   data   T452    NA      NA         NA        0

如果我的risk_codes包含例如J12,F4,T543。

1 个答案:

答案 0 :(得分:1)

我们希望立即将grepl与所有risk_codes一起应用。所以我们一次得到每行一个结果。我们可以使用sapplyany来完成此操作。

所以,我们可以放弃for循环,你的代码就像这样:

my_df <- read.table(text="Col1   Col2   Col3   Col4   Diag_1  Diag_2  Diag_3  Diag_20
data   data   data   data   J123    F456    H789       E468
data   data   data   data   T452    NA      NA         NA", header=TRUE)

risk_codes <- c("F456", "XXX") # test codes

my_df$newcol <- apply(my_df,1,function(x) 
                                  any(sapply(risk_codes, 
                                              function(codes) grepl(codes,
                                                              x[c(5:24)]))))

结果是逻辑向量。

如果您仍想使用1和0而不是TRUE / FALSE,则只需完成:

my_df$new_col <- ifelse(my_df$newcol, 1, 0)

结果将是:

> my_df
  Col1 Col2 Col3 Col4 Diag_1 Diag_2 Diag_3 Diag_20 newcol
1 data data data data   J123   F456   H789    E468      1
2 data data data data   T452   <NA>   <NA>    <NA>      0