有多少人接受了 4 种感兴趣的药物? R
how many people received 4 drugs of interest? R
我有一长串接受变量 ATC 编码药物的人。我想知道有多少人使用过 4 种特定药物。例如,我想统计有多少人使用过这种特定模式的药物 "C07ABC" & "C09XYZ" &"C08123" &"C03ZOO"。有些人可能不止一次使用过某些药剂(例如 C07 或 C08),没关系,我只想数一数有多少独特的人拥有我感兴趣的方案。我不在乎他们有多少次独特的药物。但是,因为我想查找各种模式 - 我想使用 grepl 函数。为了进一步解释这一点,我第一次尝试解决这个问题时尝试了一个求和命令:
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
您可以考虑避免使用正则表达式,而是从列 atc
派生出一些有意义的列集。对于组合,您可能需要人和药物的 2-way table,然后在矩阵上计算以计算组合。
例如:
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")
像以前一样继续。
你可以试试这个
drugs <- c("C07ABC","C09XYZ", "C08123", "C03ZOO")
table(unique(df[df$atc %in% drugs, c("names", "atc")])$names)
# john mary tom
# 4 0 0
names(which(table(unique(df[df$atc %in% drugs, c("names", "atc")])$names) > 3))
# [1] "john"
数据
df <- structure(list(names = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 3L, 3L, 3L, 3L), .Label = c("john", "mary", "tom"
), class = "factor"), fruit = structure(c(3L, 1L, 2L, 4L, 1L,
4L, 1L, 4L, 1L, 1L, 1L, 2L, 1L, 3L), .Label = c("apple", "banana",
"kiwi", "orange"), class = "factor"), dates = structure(c(5L,
7L, 8L, 9L, 10L, 3L, 5L, 5L, 7L, 8L, 1L, 2L, 4L, 6L), .Label = c("2010-02-01",
"2010-03-01", "2010-05-01", "2010-06-01", "2010-07-01", "2010-08-01",
"2010-09-01", "2010-11-01", "2010-12-01", "2011-01-01"), class = "factor"),
atc = structure(c(8L, 11L, 9L, 6L, 8L, 10L, 5L, 12L, 3L,
10L, 4L, 1L, 7L, 2L), .Label = c("C02CAMN", "C02DA12", "C03123",
"C03897", "C03QRT", "C03ZOO", "C07123", "C07ABC", "C08123",
"C09123", "C09XYZ", "C09ZOO"), class = "factor")), .Names = c("names",
"fruit", "dates", "atc"), class = "data.frame", row.names = c("4",
"7", "9", "13", "14", "2", "5", "8", "10", "12", "1", "3", "6",
"11"))
除了不需要将整个数据帧行传送到 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 的matrix/table 方法,但我认为它会更好地扩展,因为创建的"tables" 会小得多:
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
这只是@Michael Lawrence 回答的延续。我将药物更改为 @user2363642 想要的,并且我还对 atc 列进行了子字符串化以仅使用前三个字符,我相信这也是 @user2363642 想要的。此外,对于 rowSums,我首先将所有非零数量更改为 1,以确保我们不会重复计算药物。
drugs <- c("C07", "C09", "C08", "C03")
df$atc.abbr <- substring(df$atc, 1, 3)
xt <- xtabs(~ names + atc.abbr, df)
xt[xt>0] <- 1
rowSums(xt[,drugs]) >= length(drugs)
输出:
john mary tom
TRUE FALSE FALSE
我有一长串接受变量 ATC 编码药物的人。我想知道有多少人使用过 4 种特定药物。例如,我想统计有多少人使用过这种特定模式的药物 "C07ABC" & "C09XYZ" &"C08123" &"C03ZOO"。有些人可能不止一次使用过某些药剂(例如 C07 或 C08),没关系,我只想数一数有多少独特的人拥有我感兴趣的方案。我不在乎他们有多少次独特的药物。但是,因为我想查找各种模式 - 我想使用 grepl 函数。为了进一步解释这一点,我第一次尝试解决这个问题时尝试了一个求和命令:
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
您可以考虑避免使用正则表达式,而是从列 atc
派生出一些有意义的列集。对于组合,您可能需要人和药物的 2-way table,然后在矩阵上计算以计算组合。
例如:
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")
像以前一样继续。
你可以试试这个
drugs <- c("C07ABC","C09XYZ", "C08123", "C03ZOO")
table(unique(df[df$atc %in% drugs, c("names", "atc")])$names)
# john mary tom
# 4 0 0
names(which(table(unique(df[df$atc %in% drugs, c("names", "atc")])$names) > 3))
# [1] "john"
数据
df <- structure(list(names = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 3L, 3L, 3L, 3L), .Label = c("john", "mary", "tom"
), class = "factor"), fruit = structure(c(3L, 1L, 2L, 4L, 1L,
4L, 1L, 4L, 1L, 1L, 1L, 2L, 1L, 3L), .Label = c("apple", "banana",
"kiwi", "orange"), class = "factor"), dates = structure(c(5L,
7L, 8L, 9L, 10L, 3L, 5L, 5L, 7L, 8L, 1L, 2L, 4L, 6L), .Label = c("2010-02-01",
"2010-03-01", "2010-05-01", "2010-06-01", "2010-07-01", "2010-08-01",
"2010-09-01", "2010-11-01", "2010-12-01", "2011-01-01"), class = "factor"),
atc = structure(c(8L, 11L, 9L, 6L, 8L, 10L, 5L, 12L, 3L,
10L, 4L, 1L, 7L, 2L), .Label = c("C02CAMN", "C02DA12", "C03123",
"C03897", "C03QRT", "C03ZOO", "C07123", "C07ABC", "C08123",
"C09123", "C09XYZ", "C09ZOO"), class = "factor")), .Names = c("names",
"fruit", "dates", "atc"), class = "data.frame", row.names = c("4",
"7", "9", "13", "14", "2", "5", "8", "10", "12", "1", "3", "6",
"11"))
除了不需要将整个数据帧行传送到 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 的matrix/table 方法,但我认为它会更好地扩展,因为创建的"tables" 会小得多:
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
这只是@Michael Lawrence 回答的延续。我将药物更改为 @user2363642 想要的,并且我还对 atc 列进行了子字符串化以仅使用前三个字符,我相信这也是 @user2363642 想要的。此外,对于 rowSums,我首先将所有非零数量更改为 1,以确保我们不会重复计算药物。
drugs <- c("C07", "C09", "C08", "C03")
df$atc.abbr <- substring(df$atc, 1, 3)
xt <- xtabs(~ names + atc.abbr, df)
xt[xt>0] <- 1
rowSums(xt[,drugs]) >= length(drugs)
输出:
john mary tom
TRUE FALSE FALSE