R:将数据框元素与矢量元素匹配

时间:2018-12-04 22:14:58

标签: r dataframe

我正在处理包含ICD代码的大型患者数据数据框,我想查看列表中是否有任何代码与预定义列表中的代码匹配。我希望将测试结果作为新列输出到我的数据框中。理想情况下,我想从这样的角度出发:

dx1   dx2   dx3  ...  dx15
4210  3359  2214      8178
V0832 12218 7423      2294
6463  3438  3243      1129

对于这样的事情:

dx1   dx2   dx3  ...  dx15  ENDO
4210  3359  4211      8178  TRUE
V0832 12218 7423      2294  TRUE
6463  3438  E3243      1129  FALSE

我用感兴趣的代码创建了一个向量:

ICD9EndoCodes <-c("4210","4211","4219","4249","421","11281")

但是还无法弄清楚如何对我的数据帧的元素执行逻辑测试并输出单个列。我最接近的是:

x <-ifelse(df_04_13[,4:18] == "4210", TRUE, FALSE)

...这将创建矩阵“ x”,并为矩阵中的每个位置正确分配了正确和错误。但是当我对它进行概括时……

x <- for(i in 1:length(ICD9EndoCodes)) 
     ifelse(df_04_13[,4:18] == ICD9EndoCodes[i], TRUE, FALSE)

我得到“ null”。我觉得自己正在忽略一种显而易见的,直接的方法来解决此问题,但是我对环境的不熟悉使我感到挣扎。

3 个答案:

答案 0 :(得分:1)

我是作者的icd软件包就是这样做的:

library(icd) pts <- data.frame(id = c("pt1", "pt2"), dx1 = c("410", "V10"), dx2 = c("4219", "11281"), stringsAsFactors = FALSE) ICD9EndoCodes <-c("4210","4211","4219","4249","421","11281") res <- icd::comorbid(pts, map = list(endo = ICD9EndoCodes)) cbind(pts, res) id dx1 dx2 endo pt1 pt1 410 4219 TRUE pt2 pt2 V10 11281 TRUE introduction和其他文档中有使用自定义映射(如本示例)以及Elixhauser,Quan,Charlson等的标准映射的合并症计算示例。

答案 1 :(得分:0)

这是使用instance Semigroup MyMonoid where MyMonoid m1 <> MyMonoid m2 = MyMonoid (S.union m1 m2) instance Monoid MyMonoid where mempty = MyMonoid S.empty 的一种解决方案:

tidyverse

样本数据:

df %>%
 mutate_all(funs(ifelse(. %in% ICD9EndoCodes, 1, 0))) %>% #Comparing the values in df with the values in the vector and assigning 1 when there is a match
 mutate(ENDO = ifelse(rowSums(.) >= 1, TRUE, FALSE)) %>% #Counting the number of matches
 select(ENDO) %>%
 rowid_to_column() %>%
 left_join(df %>%
            rowid_to_column(), by = c("rowid" = "rowid")) %>% #Merging the results with the original df
 select(-rowid)

   ENDO   dx1   dx2  dx3 dx15
1  TRUE  4210  4211 2214 8178
2 FALSE V0832 12218 7423 2294
3 FALSE  6463  3438 3243 1129

答案 2 :(得分:0)

下面是不重塑数据的一种方法的示例:

dat <- read.table(text="id dx1   dx2   dx3  dx15
1 4210  3359  2214  8178
2 V0832 12218 7423  2294
3 6463  3438  3243  1129", header=TRUE, stringsAsFactors=FALSE)

遍历每列,并检查是否有任何值与列表中的ICD代码匹配。然后使用Reduce()函数(代表“ OR”)通过|折叠每个列指示符,以获取行级指示符:

Reduce(`|`, lapply(dat[2:5], `%in%`, ICD9EndoCodes))
#[1]  TRUE FALSE FALSE

尽管我怀疑从长远来看(“双关语”)这种类型的数据更容易以“长期”形式使用。如果大多数患者仅进行1或2次诊断,而不是每个人都统一记录15次,那么这也是最有效,更灵活的ICD代码存储方式。

标记/聚集/合并。无论您有1 dxN列(15还是115),此逻辑都将起作用,因为它们现在都折叠到了一个列中。例如:

long <- cbind(dat[1], stack(dat[-1]))

# flag
long$icdhit <- long$values %in% ICD9EndoCodes

# aggregate
icdagg <- aggregate(icdhit ~ id, data=long, FUN=any)
#  id icdhit
#1  1   TRUE
#2  2  FALSE
#3  3  FALSE

# merge
merge(dat, icdagg, by="id", all.x=TRUE)
#  id   dx1   dx2  dx3 dx15 icdhit
#1  1  4210  3359 2214 8178   TRUE
#2  2 V0832 12218 7423 2294  FALSE
#3  3  6463  3438 3243 1129  FALSE