在 table 中查找超过第三个四分位数的频率
Find frequencies over 3rd quartile in table
我有一个大数据框(+239k 对 57 个变量的观察),其中包含一些疾病描述和针对不同年龄段人群的这些疾病的药物。我想在每种疾病描述中找到使用频率最高的四分之一的药物。
为了制作一个可重现的例子,我创建了一个包含 1000 个观察值的数据框:
set.seed(1);sk<-as.factor(sample(c("sick A","sick B","sick C","sick D"),1000,replace=T));md<-as.factor(sample(c("med 1","med 2","med 3","med 4","med 5")));age<-as.factor(sample(c("group a","group b","group c"),1000,replace=T))
df<-data.frame(obs=1:1000,md=md,sk=sk,age=age)
我可以产生 table 的频率
xt<-xtabs(~md+sk+age,df)
然后我可以为每个年龄组生成一个数据框
XTDF_a<-as.data.frame(xt[,,"group a"])
然后找到每种疾病频率的第三个四分位数:
Q3_a<-apply(XTDF_a,2,function(x) quantile(x,probs = .75))
我可以比较并获得哪些药物超过每种疾病的第三个四分位数
XTDF_a>Q3_a
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE TRUE FALSE
med 2 FALSE FALSE FALSE FALSE
med 3 TRUE TRUE FALSE FALSE
med 4 FALSE FALSE FALSE TRUE
med 5 FALSE FALSE FALSE FALSE
我可以得出结论,med 3
是疾病 A 的首选,依此类推(我正在循环提取该信息)。然后我回去重复 b、c 组的过程....这对于我拥有的数据量来说几乎是不可能的(疾病大约是 4200 级,药物大约是 1150 级)。
我很确定应该有一种不同的、更简单的方法来实现这一点。如果能提供更好的路径提示,我将不胜感激。
apply
可以处理 3 维数组,并且可以指定多个维度进行迭代:
> apply(xt,2:3,function(x) x > quantile(x, probs = .75))
, , age = group a
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE TRUE FALSE
med 2 FALSE FALSE FALSE FALSE
med 3 TRUE TRUE FALSE FALSE
med 4 FALSE FALSE FALSE TRUE
med 5 FALSE FALSE FALSE FALSE
, , age = group b
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE TRUE FALSE
med 2 FALSE FALSE FALSE FALSE
med 3 FALSE FALSE FALSE FALSE
med 4 TRUE FALSE FALSE FALSE
med 5 FALSE TRUE FALSE FALSE
, , age = group c
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE FALSE TRUE
med 2 FALSE FALSE FALSE FALSE
med 3 FALSE FALSE FALSE FALSE
med 4 FALSE FALSE FALSE FALSE
med 5 TRUE FALSE FALSE FALSE
我认为您可以通过编写更精确的函数然后使用 aggregate
获得结果来加快速度。如果您想要更基于列表的方法,您也可以使用 by
,这可能对您下次使用更有用。我认为它仍然会很慢,但不会像循环一样慢。
# Here is what you gave me originally
set.seed(1)
sk<-as.factor(sample(c("sick A","sick B","sick C","sick D"),1000,replace=T))
md<-as.factor(sample(c("med 1","med 2","med 3","med 4","med 5")))
age<-as.factor(sample(c("group a","group b","group c"),1000,replace=T))
df<-data.frame(obs=1:1000,md=md,sk=sk,age=age)
# Define a function that basically does what you did before, but uses table()
func.get_75th_meds <- function(vector_of_meds) {
freq <- table(vector_of_meds)
return(names(freq)[freq >= quantile(x = freq,probs = 0.75)])
}
aggregate(x = list(Meds = df$md),
by = list(Sickness = df$sk,Group = df$age),
FUN = func.get_75th_meds)
Sickness Group Meds
1 sick A group a med 3, med 5
2 sick B group a med 3, med 5
3 sick C group a med 1, med 2, med 4, med 5
4 sick D group a med 2, med 4
5 sick A group b med 4, med 5
6 sick B group b med 1, med 2, med 5
7 sick C group b med 1, med 2
8 sick D group b med 2, med 3
9 sick A group c med 2, med 5
10 sick B group c med 2, med 4
11 sick C group c med 1, med 2, med 4
12 sick D group c med 1, med 3, med 4
编辑添加:这是 by()
使用相同功能的替代方法。
by(data = df$md,
INDICES = list(Sickness = df$sk,Group = df$age),
FUN = func.get_75th_meds)
Sickness: sick A
Group: group a
[1] "med 3" "med 5"
---------------------------------------------------------------
Sickness: sick B
Group: group a
[1] "med 3" "med 5"
---------------------------------------------------------------
... and so on
我有一个大数据框(+239k 对 57 个变量的观察),其中包含一些疾病描述和针对不同年龄段人群的这些疾病的药物。我想在每种疾病描述中找到使用频率最高的四分之一的药物。
为了制作一个可重现的例子,我创建了一个包含 1000 个观察值的数据框:
set.seed(1);sk<-as.factor(sample(c("sick A","sick B","sick C","sick D"),1000,replace=T));md<-as.factor(sample(c("med 1","med 2","med 3","med 4","med 5")));age<-as.factor(sample(c("group a","group b","group c"),1000,replace=T))
df<-data.frame(obs=1:1000,md=md,sk=sk,age=age)
我可以产生 table 的频率
xt<-xtabs(~md+sk+age,df)
然后我可以为每个年龄组生成一个数据框
XTDF_a<-as.data.frame(xt[,,"group a"])
然后找到每种疾病频率的第三个四分位数:
Q3_a<-apply(XTDF_a,2,function(x) quantile(x,probs = .75))
我可以比较并获得哪些药物超过每种疾病的第三个四分位数
XTDF_a>Q3_a
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE TRUE FALSE
med 2 FALSE FALSE FALSE FALSE
med 3 TRUE TRUE FALSE FALSE
med 4 FALSE FALSE FALSE TRUE
med 5 FALSE FALSE FALSE FALSE
我可以得出结论,med 3
是疾病 A 的首选,依此类推(我正在循环提取该信息)。然后我回去重复 b、c 组的过程....这对于我拥有的数据量来说几乎是不可能的(疾病大约是 4200 级,药物大约是 1150 级)。
我很确定应该有一种不同的、更简单的方法来实现这一点。如果能提供更好的路径提示,我将不胜感激。
apply
可以处理 3 维数组,并且可以指定多个维度进行迭代:
> apply(xt,2:3,function(x) x > quantile(x, probs = .75))
, , age = group a
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE TRUE FALSE
med 2 FALSE FALSE FALSE FALSE
med 3 TRUE TRUE FALSE FALSE
med 4 FALSE FALSE FALSE TRUE
med 5 FALSE FALSE FALSE FALSE
, , age = group b
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE TRUE FALSE
med 2 FALSE FALSE FALSE FALSE
med 3 FALSE FALSE FALSE FALSE
med 4 TRUE FALSE FALSE FALSE
med 5 FALSE TRUE FALSE FALSE
, , age = group c
sk
md sick A sick B sick C sick D
med 1 FALSE FALSE FALSE TRUE
med 2 FALSE FALSE FALSE FALSE
med 3 FALSE FALSE FALSE FALSE
med 4 FALSE FALSE FALSE FALSE
med 5 TRUE FALSE FALSE FALSE
我认为您可以通过编写更精确的函数然后使用 aggregate
获得结果来加快速度。如果您想要更基于列表的方法,您也可以使用 by
,这可能对您下次使用更有用。我认为它仍然会很慢,但不会像循环一样慢。
# Here is what you gave me originally
set.seed(1)
sk<-as.factor(sample(c("sick A","sick B","sick C","sick D"),1000,replace=T))
md<-as.factor(sample(c("med 1","med 2","med 3","med 4","med 5")))
age<-as.factor(sample(c("group a","group b","group c"),1000,replace=T))
df<-data.frame(obs=1:1000,md=md,sk=sk,age=age)
# Define a function that basically does what you did before, but uses table()
func.get_75th_meds <- function(vector_of_meds) {
freq <- table(vector_of_meds)
return(names(freq)[freq >= quantile(x = freq,probs = 0.75)])
}
aggregate(x = list(Meds = df$md),
by = list(Sickness = df$sk,Group = df$age),
FUN = func.get_75th_meds)
Sickness Group Meds
1 sick A group a med 3, med 5
2 sick B group a med 3, med 5
3 sick C group a med 1, med 2, med 4, med 5
4 sick D group a med 2, med 4
5 sick A group b med 4, med 5
6 sick B group b med 1, med 2, med 5
7 sick C group b med 1, med 2
8 sick D group b med 2, med 3
9 sick A group c med 2, med 5
10 sick B group c med 2, med 4
11 sick C group c med 1, med 2, med 4
12 sick D group c med 1, med 3, med 4
编辑添加:这是 by()
使用相同功能的替代方法。
by(data = df$md,
INDICES = list(Sickness = df$sk,Group = df$age),
FUN = func.get_75th_meds)
Sickness: sick A
Group: group a
[1] "med 3" "med 5"
---------------------------------------------------------------
Sickness: sick B
Group: group a
[1] "med 3" "med 5"
---------------------------------------------------------------
... and so on