如何编写一个函数,即使跨列匹配多个匹配也可以计算一次

时间:2016-07-29 19:08:02

标签: r function

我有一个数据集,其中包含患者诊断(ICD-9)代码,其长度在3-5位之间,前三位代表诊断分类,第4和第5代表进一步细化的分类。例如:

zz<-"     dx1   dx2   dx3
1  64251 82381  8100
2   8052  8730 51881
3  64421   431 81601
4   3041 29690  9920
5  72888  8782 59080
6   7245 60886  8479
7    291  4659  4739
8  30410 30400 95901
9   2929 30500  8208
10  7840  6268  8052"
df<-read.table(text=zz, header=TRUE)

每行代码代表同一个人的多个诊断。我编写了一系列ifelse语句来创建一个我感兴趣的代码的新变量,因此它们被映射到代表不同感兴趣诊断的数字:

df$x<-ifelse(grepl("^291", dx1),1, ifelse(grepl("^292", dx1),1 
       ifelse(grepl("^3040", dx1),2,ifelse(grepl("^3047", dx1),2,
       ifelse(grepl("^3051", dx1),3,ifelse(grepl("^98984", dx1),3,0))))))

当我遇到麻烦时,我想在每个包含诊断代码的列中检查这些选择代码。我试图为此写一个函数:

df$alldx<-apply(df[,c(1:3)],MARGIN = 2, function(dx){
  ifelse(grepl("^291", dx),1, ifelse(grepl("^292", dx),1 
  ifelse(grepl("^3040", dx),2,ifelse(grepl("^3047", dx),2,
  ifelse(grepl("^3051", dx),3,ifelse(grepl("^98984", dx),3,0)))))) 
})

问题是如果他们有一个感兴趣的代码,我只想计算一个人;在多个代码匹配的情况下,那个人的代码应该是首先给出的诊断。我觉得必须有办法做到这一点,但它远远超出了我的编码能力!

1 个答案:

答案 0 :(得分:3)

这就是我要做的事情,为方便起见,使用data.table包:

library(data.table)
setDT(df)[, id := .I]

DF = melt(df, id="id")[, 
  `:=`(diag = substr(value, 1, 3), ref = substr(value, 4, 5))][order(id)]

所以现在数据看起来像

    id variable value diag ref
 1:  1      dx1 64251  642  51
 2:  1      dx2 82381  823  81
 3:  1      dx3  8100  810   0
 4:  2      dx1  8052  805   2
 5:  2      dx2  8730  873   0
 6:  2      dx3 51881  518  81
 7:  3      dx1 64421  644  21
 8:  3      dx2   431  431    
 9:  3      dx3 81601  816  01
10:  4      dx1  3041  304   1
11:  4      dx2 29690  296  90
12:  4      dx3  9920  992   0
13:  5      dx1 72888  728  88
14:  5      dx2  8782  878   2
15:  5      dx3 59080  590  80
16:  6      dx1  7245  724   5
17:  6      dx2 60886  608  86
18:  6      dx3  8479  847   9
19:  7      dx1   291  291    
20:  7      dx2  4659  465   9
21:  7      dx3  4739  473   9
22:  8      dx1 30410  304  10
23:  8      dx2 30400  304  00
24:  8      dx3 95901  959  01
25:  9      dx1  2929  292   9
26:  9      dx2 30500  305  00
27:  9      dx3  8208  820   8
28: 10      dx1  7840  784   0
29: 10      dx2  6268  626   8
30: 10      dx3  8052  805   2
    id variable value diag ref

其中id是患者ID,diag是诊断,ref是细化,如果有的话。我们可以看到示例数据中的诊断没有太多重复:

DF[, sum(duplicated(diag)), by=id]

    id V1
 1:  1  0
 2:  2  0
 3:  3  0
 4:  4  0
 5:  5  0
 6:  6  0
 7:  7  0
 8:  8  1
 9:  9  0
10: 10  0

现在,如果我们想要计算有多少患者诊断为304,我们可以这样做:

DF[diag == "304", uniqueN(id)]

[1] 2

如果您希望将代码映射到新代码(这可能比其他任何代码更令人困惑),我建议您通过创建一个单独的表来描述映射并合并它来分配新代码。我认为data.table也很方便。 The intro materials for the package是开始使用它的好地方。

合并的简短示例:

m = fread("
diag new_code
291 1
292 1 
304 2
305 3
989 3", colClasses=c(diag = "character"))

DF[m, on="diag", new_code := i.new_code ]