【问题标题】:R - return boolean if any strings in a vector appear in any of several columnsR - 如果向量中的任何字符串出现在几列中的任何一列中,则返回布尔值
【发布时间】:2016-06-26 11:42:44
【问题描述】:

我有一个大数据框,其中每一行都表示入院。每次入院时在第 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。

【问题讨论】:

  • 我提交了一个答案,但现在重新阅读问题后,我不确定我是否理解正确。当 risk_code 和 Diag_ 完美匹配时,您是否想要新 col 中的 1,或者如果有部分匹配,它也是 1。 eg:J123和J1到底应该是1?
  • 部分匹配。如果J123是数据框中的诊断码,那么J123、J12和J1的risk_codes都应该返回1。

标签: r string dataframe apply grepl


【解决方案1】:

我们希望一次应用带有所有 risk_code 的 grepl。所以我们一次得到每行一个结果。我们可以使用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

【讨论】:

  • 谢谢,这样可以识别很多相关记录。但是,例如,如果 risk_codes 的向量由 c("F45", "XXX") 组成,它会在新列中返回 1 吗?如果逐个搜索字符串,则 grepl 函数允许这样做。我需要“F45”作为搜索的成功结果,因为 F45 的代码是数据框中 F456 的子集。
  • 我误解了这个问题。现在我更新了答案。基本上我正在用函数(x)内部的一个 sapply 调用替换你的外部 for 循环。
  • 效果很好。真的非常感谢!我需要仔细阅读有关 apply 和 sapply 函数的一些说明!
  • 尝试使用sum 而不是any。它应该计算 TRUE 值的数量。
猜你喜欢
  • 2022-12-10
  • 2021-10-28
  • 2018-06-02
  • 2012-10-10
  • 2021-07-31
  • 1970-01-01
  • 2021-02-11
  • 1970-01-01
  • 2022-09-23
相关资源
最近更新 更多