首页 > 解决方案 > ifelse/case_when 在字符向量中带有看似棘手的字符串

问题描述

我有一个死亡率数据框,其字符向量 ( rac) 每行包含不同的字符串。这些字符串标记了导致死亡的原因。有时这些字符串之间有一个额外的空格(请参阅 参考资料id = 4, 5, 8)。有时它们正好有 3 个字符,有时它们有 4 个字符。我要做的是逐行扫描并创建一个新列,该列标记是否在 rac 中看到了特定的死因。这是数据。

tdf <- structure(list(id = 1:10, rac = c("I250", "K922 R628", 
"C259 T149 X599", "K729 C80  J80  N288", "X72  S019", "C189", 
"C259 A419 K746 N390", "C349 C787 C793 C795 F179 I10  J449", 
"C349 J449 R628", "F03  N189 R628")), row.names = c(NA, -10L), 
class = "data.frame")

采取id = 8,我可以轻松地创建一个名为 cause_c 的标志,以记录何时C793C795看到类似此片段的内容。

causex <- c("\\bC793|\\bC795")
tdf %>%
  mutate(
    cause_C = case_when(
      str_detect(rac, causex) ~ 1,
      TRUE ~ 0)
  ) -> tdf

它似乎有效,但我希望能够在向量仅显示 3 位数字的情况下进行扫描,例如,C79当这种情况发生时,cause_C应该= 1。这也是一种更有效的创建标志的方法,因为这样我就不必拼出所有可能的代码版本(C793、C794、C79 等),并且因为我有多个原因需要通过和标志大约 16 种可能的死亡原因。但是,如果我尝试以下id = 8操作,最终将全部为 0。

tdf %>%
  mutate(
    cause_C = case_when(
      str_sub(rac, 1, 3) == "C79" ~ 1,
      TRUE ~ 0)
  ) -> tdf

ifelse()\case_when() 解决方案缺少一些东西,如果有人发现我的错误和修复,我将非常感激!哦,base-R、data.table()、dplyr(),所有解决方案都是受欢迎的,因为我也很高兴看到速度比较,因为数据帧正在咀嚼超过 1.5 个演出。

谢谢!

阿尼

标签: rdplyrdata.table

解决方案


如果您想使用data.table,您会考虑按诊断代码拆分行,然后用于grepl匹配您所需诊断的向量吗?

library(data.table)

causex <- c("C793", "C795")

search_causex <- paste(causex, collapse = "|")

setDT(tdf, key = "rac")
tdf[, list(rac = unlist(strsplit(rac, " "))), by = id][
  , result := grepl(search_causex, rac)][
    result == TRUE]

如果你想用更少的字符搜索,你可以使用这个搜索模式:

search_causex <- "C79(.+)"

类似的tidyverse方法可能是:

library(tidyverse)

tdf %>%
  separate_rows(rac, sep = " ") %>%
  filter(grepl(search_causex, rac) == TRUE)

推荐阅读