我有一长串人接受使用可变ATC编码的药物。我想找出有多少人使用了4种特定药物。例如,我想计算有多少人使用了这种特殊模式的药物“ C07ABC”和“ C09XYZ”和“ C08123”和“ C03ZOO”。有些人可能不止一次使用过某些代理(例如C07或C08),没关系,我只想计算有多少独特的人拥有我感兴趣的方案。我不在乎他们有多少次拥有独特的方案毒品。但是,由于我想查找各种模式-我想使用grepl函数。为了进一步解释这一点,我对这个问题的第一次尝试是使用sum命令:
sum(df[grepl('^C07.*?'|'^C09.*?'|'^C08.*?|C03.*?', as.character(df$atc)),])
但是这不起作用,因为我认为sum命令需要一个布尔函数。另外,我认为此处的符号也不正确(我想要一个&),但我只是在显示代码,以便您知道我在追求什么。也许我需要ave函数-但不确定如何编写此代码?
谢谢。
df
names fruit dates atc
4 john kiwi 2010-07-01 C07ABC
7 john apple 2010-09-01 C09XYZ
9 john banana 2010-11-01 C08123
13 john orange 2010-12-01 C03ZOO
14 john apple 2011-01-01 C07ABC
2 mary orange 2010-05-01 C09123
5 mary apple 2010-07-01 C03QRT
8 mary orange 2010-07-01 C09ZOO
10 mary apple 2010-09-01 C03123
12 mary apple 2010-11-01 C09123
1 tom apple 2010-02-01 C03897
3 tom banana 2010-03-01 C02CAMN
6 tom apple 2010-06-01 C07123
11 tom kiwi 2010-08-01 C02DA12
除了不需要将整个数据帧行传送到sum
之外,该模式中还带有额外的引号:
> sum( grepl('^C07.*|^C09.*|^C08.*|C03.*', df$atc) )
[1] 12
我认为这更容易阅读:
> sum( grepl('^(C07|C09|C08|C03).*', df$atc) )
[1] 12
但是现在我读到您希望使用所有方法并在患者ID中进行计算。可能需要使用&作为连接器,但我决定尝试其他路由并使用unique
,然后在aggregate
操作中进行操作时先计算唯一匹配的次数。
> aggregate(atc ~ names, data=df,
function(drgs) length(unique(grep('^(C07|C09|C08|C03)', drgs))))
names atc
1 john 5
2 mary 5
3 tom 2
尽管这是匹配项的数量,但不是唯一项的数量,因为我忘记在grep
调用中放入value = TRUE(并且还需要使用substr
以避免分别计算具有不同尾随ATC代码的同类对象):
> aggregate(atc ~ names, data=df, function(drgs) length(unique(grep('^C0[7983]', substr(drgs,1,3), value=TRUE))))
names atc
1 john 4
2 mary 2
3 tom 2
这有点类似于@MichaelLawrence的矩阵/表方法,但是我认为它会更好地扩展,因为创建的“表”要小得多:
combo <- c("C07", "C09", "C08", "C03")
tapply(df$atc, df$names, function(drgs) sum(combo %in% substr(drgs,1,3)) )
#------
john mary tom
4 2 2
您可能考虑避免使用正则表达式,而是从列atc
派生出一组有意义的列。对于组合,您可能需要一个2人和毒品的双向表,然后在矩阵上进行计算以计算组合。
例如:
tab <- xtabs(~ names + atc, df)
combo <- c("C07ABC", "C09XYZ", "C08123", "C03ZOO")
haveCombo <- rowSums(tab[,combo] > 0) == length(combo)
sum(haveCombo)
最后两行可以很容易地变成每种组合的功能。
编辑:此方法可以应用于其他派生列,因此,如果您对前缀感兴趣,则],>
df$agent <- substring(df$atc, 1, 3) tab <- xtabs(~ names + agent, df) combo <- c("C07", "C09", "C08", "C03")
并像以前一样进行。
您可以尝试这个
这只是@Michael Lawrence回答的延续。我将药物更改为@ user2363642所需的内容,并且还对atc列加了字符串以仅使用前三个字符,我相信这也是@ user2363642想要的。另外,对于rowSums,我首先将所有非零数量更改为1,以确保我们不会对药物进行重复计数。