如何计算R中各组的中位数
数据的小例子如何计算R中各组的中位数,r,dplyr,plyr,lapply,R,Dplyr,Plyr,Lapply,数据的小例子 df=structure(list(Dt = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 38L, 39L, 1L, 2L, 3L, 4L,
df=structure(list(Dt = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L,
9L, 10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L,
22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L,
35L, 36L, 37L, 38L, 39L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L,
10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L,
23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L,
36L, 37L, 38L, 39L), .Label = c("2018-02-20 00:00:00.000", "2018-02-21 00:00:00.000",
"2018-02-22 00:00:00.000", "2018-02-23 00:00:00.000", "2018-02-24 00:00:00.000",
"2018-02-25 00:00:00.000", "2018-02-26 00:00:00.000", "2018-02-27 00:00:00.000",
"2018-02-28 00:00:00.000", "2018-03-01 00:00:00.000", "2018-03-02 00:00:00.000",
"2018-03-03 00:00:00.000", "2018-03-04 00:00:00.000", "2018-03-05 00:00:00.000",
"2018-03-06 00:00:00.000", "2018-03-07 00:00:00.000", "2018-03-08 00:00:00.000",
"2018-03-09 00:00:00.000", "2018-03-10 00:00:00.000", "2018-03-11 00:00:00.000",
"2018-03-12 00:00:00.000", "2018-03-13 00:00:00.000", "2018-03-14 00:00:00.000",
"2018-03-15 00:00:00.000", "2018-03-16 00:00:00.000", "2018-03-17 00:00:00.000",
"2018-03-18 00:00:00.000", "2018-03-19 00:00:00.000", "2018-03-20 00:00:00.000",
"2018-03-21 00:00:00.000", "2018-03-22 00:00:00.000", "2018-03-23 00:00:00.000",
"2018-03-24 00:00:00.000", "2018-03-25 00:00:00.000", "2018-03-26 00:00:00.000",
"2018-03-27 00:00:00.000", "2018-03-28 00:00:00.000", "2018-03-29 00:00:00.000",
"2018-03-30 00:00:00.000"), class = "factor"), ItemRelation = c(158043L,
158043L, 158043L, 158043L, 158043L, 158043L, 158043L, 158043L,
158043L, 158043L, 158043L, 158043L, 158043L, 158043L, 158043L,
158043L, 158043L, 158043L, 158043L, 158043L, 158043L, 158043L,
158043L, 158043L, 158043L, 158043L, 158043L, 158043L, 158043L,
158043L, 158043L, 158043L, 158043L, 158043L, 158043L, 158043L,
158043L, 158043L, 158043L, 234L, 234L, 234L, 234L, 234L, 234L,
234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L,
234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L,
234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L, 234L
), stuff = c(200L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 3600L,
0L, 0L, 0L, 0L, 700L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 1000L, 2600L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 400L, 700L,
200L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 3600L, 0L, 0L, 0L,
0L, 700L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1000L,
2600L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 400L, 700L), num = c(1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L, 1459L,
1459L, 1459L, 1459L, 1459L, 1459L), year = c(2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L,
2018L, 2018L, 2018L), action = c(0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 1L, 1L, 1L, 1L)), .Names = c("Dt", "ItemRelation",
"stuff", "num", "year", "action"), class = "data.frame", row.names = c(NA,
-78L))
现在每组
ItemRelation+num+年份我必须计算中位数。
如果我使用这个解决方案
# df with action 0 and stuff > 0
v <- df$stuff[intersect(which(df$action == 0),
which(df$stuff > 0))]
# df with action 1 and stuff > 0
w <- df$stuff[intersect(which(df$action == 1),
which(df$stuff > 0))]
# calulating the median of v for the last 5 observations
l <- length(v)
m0 <- median(v[(l-4):l]) # taking the median of the last 5 observations
# computing the final difference
m <- median(w) - m0
后期编辑。请注意,值不是实值,中间值将是另一个,我只是想显示我希望输出的内容
编辑
action列只有两个值0和1。我必须用一个类别前的最后五个整数值,计算一个类别的动作的中位数,然后用零个类别的动作的中位数。我只取最后5个观察值,有必要取零类动作的最后5个观察值,但只取整数值,而不是计算所有零类值的中值。在我们的例子中,这是
200
3600
700
1000
2600
然后从一个类别的中值中减去零个类别的中值
零行动类别的观察次数可以从0到10不等。如果我们有10个零类别的整数值,我们取最后5个。如果只有1,2,3,4,5个整数值,我们减去整数值实数的中值。如果我们只有0而没有整数,我们只需要子动作0
但代码必须按零类别计算中值,但在一个类别之前必须计算最后5个obs
请注意,零操作类别可能有其他值,而不是0。最简单的方法是使用
dplyr
包中的groupby
和summary
:
库(dplyr)
#群体中位数
中间值%
分组依据(项目关系、数量、年份)%>%
汇总(平均值=中位数(stuff,na.rm=T))
#各组非零值的中值
中间值%
过滤器(填充>0)%>%
分组依据(项目关系、数量、年份)%>%
汇总(平均值=中位数(stuff,na.rm=T))
减去%
突变(med_diff=减法(med))
最简单的方法是使用dplyr
软件包中的groupby
和summary
:
库(dplyr)
#群体中位数
中间值%
分组依据(项目关系、数量、年份)%>%
汇总(平均值=中位数(stuff,na.rm=T))
#各组非零值的中值
中间值%
过滤器(填充>0)%>%
分组依据(项目关系、数量、年份)%>%
汇总(平均值=中位数(stuff,na.rm=T))
减去%
突变(med_diff=减法(med))
使用dplyr
和以下提到的步骤可以实现一种解决方案。请在下面的代码中找到方法的注释
注意:OP中的样本数据本身似乎意义不大
library(dplyr)
df %>% filter(stuff > 0) %>% #First filter out for stuff > 0 which of our interest
group_by(ItemRelation, num, year) %>%
mutate(m = median(stuff[action==1]),
m0 = median(tail(stuff[action==0], 5))) %>% # Calculate m and m0 for all rows
filter(action == 1) %>% # Now keep only rows with action == 1
mutate(m = m-m0) %>%
select(-Dt,-m0,-action)
# # A tibble: 4 x 5
# # Groups: ItemRelation, num, year [2]
# ItemRelation stuff num year m
# <int> <int> <int> <int> <dbl>
# 1 158043 400 1459 2018 -450
# 2 158043 700 1459 2018 -450
# 3 234 400 1459 2018 -450
# 4 234 700 1459 2018 -450
库(dplyr)
df%>%筛选(素材>0)%>%#首先筛选出我们感兴趣的素材>0
分组依据(项目关系、数量、年份)%>%
突变(m=中位数(stuff[action==1]),
m0=中间值(尾部(填充[action==0],5))%>%#计算所有行的m和m0
筛选器(操作==1)%>%#现在只保留操作==1的行
突变(m=m-m0)%>%
选择(-Dt,-m0,-动作)
##A tibble:4 x 5
##组:项目关系,数量,年份[2]
#ItemRelationship num第m年
#
# 1 158043 400 1459 2018 -450
# 2 158043 700 1459 2018 -450
# 3 234 400 1459 2018 -450
# 4 234 700 1459 2018 -450
使用dplyr
和以下提到的步骤可以实现一种解决方案。请在下面的代码中找到方法的注释
注意:OP中的样本数据本身似乎意义不大
library(dplyr)
df %>% filter(stuff > 0) %>% #First filter out for stuff > 0 which of our interest
group_by(ItemRelation, num, year) %>%
mutate(m = median(stuff[action==1]),
m0 = median(tail(stuff[action==0], 5))) %>% # Calculate m and m0 for all rows
filter(action == 1) %>% # Now keep only rows with action == 1
mutate(m = m-m0) %>%
select(-Dt,-m0,-action)
# # A tibble: 4 x 5
# # Groups: ItemRelation, num, year [2]
# ItemRelation stuff num year m
# <int> <int> <int> <int> <dbl>
# 1 158043 400 1459 2018 -450
# 2 158043 700 1459 2018 -450
# 3 234 400 1459 2018 -450
# 4 234 700 1459 2018 -450
库(dplyr)
df%>%筛选(素材>0)%>%#首先筛选出我们感兴趣的素材>0
分组依据(项目关系、数量、年份)%>%
突变(m=中位数(stuff[action==1]),
m0=中间值(尾部(填充[action==0],5))%>%#计算所有行的m和m0
筛选器(操作==1)%>%#现在只保留操作==1的行
突变(m=m-m0)%>%
选择(-Dt,-m0,-动作)
##A tibble:4 x 5
##组:项目关系,数量,年份[2]
#ItemRelationship num第m年
#
# 1 158043 400 1459 2018 -450
# 2 158043 700 1459 2018 -450
# 3 234 400 1459 2018 -450
# 4 234 700 1459 2018 -450
对于num
,您的示例数据只有1459,而您的预期输出为num==234
。请修复。@用户,你是对的,我修复了它。请检查。请参阅tapply
@Noah的文档。我尝试使用lappy和tapply,但没有得到结果。如何更正?您的示例数据只有1459的num
,而您的预期输出为num==234
。请修复。@用户,你是对的,我修复了它。请检查。请参阅tapply
@Noah的文档。我尝试使用lappy和tapply,但没有得到结果。如何做正确?Özgen Eren,请注意,您将看到,我所给出的动作分类工作。我们计算组和行动的中位数=1,组和行动的中位数=0,而不是子行动。请考虑我的代码。奥齐ZGEN,我编辑了一篇文章来澄清我的问题,你能检查一下吗?也可能需要确保X中的订单是正确的。你可以传递2个变量action和med,如果这很重要的话,请注意,你会看到,我给出的关于动作类别的工作。我们计算组和行动的中位数=1,组和行动的中位数=0,而不是子行动。请考虑我的代码。奥齐ZGEN,我编辑了一篇文章来澄清我的问题,你能检查一下吗?也可能需要确保X中的订单是正确的。你可以传递2个变量action和med如果这很重要,我可以请你在这个相关的主题中提供帮助。请继续回答@乔:我给你的新问题加了一个答案。看一看如果你的答案符合你的期望,你可以接受,这样对未来的用户会有帮助。MKR,我可以请你在这个相关的话题上提供帮助吗。请继续回答@乔:我给你的新问题加了一个答案。看一看如果符合您的要求,您可以接受答案