基于R中的多个索引进行应用
tapply based on multiple indexes in R
我有一个数据框,很像这个:
ref=rep(c("A","B"),each=240)
year=rep(rep(2014:2015,each=120),2)
month=rep(rep(1:12,each=10),4)
values=c(rep(NA,200),rnorm(100,2,1),rep(NA,50),rnorm(40,4,2),rep(NA,90))
DF=data.frame(ref,year,month,values)
我想计算每年每个参考文献的最大连续 NA 数。
我创建了一个函数,它计算出连续NA的最大数量,但只能基于一个变量。
例如,
func <- function(x) {
max(rle(is.na(x))$lengths)
}
with(DF, tapply(values,ref, func))
# A B
# 200 90
with(DF, tapply(values,year, func))
# 2014 2015
# 120 90
所以在ref A中总共最多有200个连续的NA,在ref B中最多有90个,这是正确的。 2014年还有120个NA,2015年有90个
我想要的是每个 ref 和年份的结果,例如:
A 2015 80
A 2014 120
B 2015 90
B 2014 50
有多种方法可以做到这一点,一种是使用 plyr 库:
library(plyr)
ddply(DF,c('ref','year'),summarise,NAs=max(rle(is.na(values))$lengths))
ref year NAs
1 A 2014 120
2 A 2015 80
3 B 2014 60
4 B 2015 90
使用你的函数,你也可以试试:
with(DF, tapply(values,list(ref,year), func))
输出略有不同
2014 2015
A 120 80
B 60 90
通过使用 melt(),您可以获得相同的数据帧。
我喜欢食谱格式
library(dplyr)
DF$values[is.na(DF$values)] <- 1
DF %>%
filter(values==1) %>%
group_by(ref,year) %>%
mutate(csum=cumsum(values)) %>%
group_by(ref,year) %>%
summarise(max(csum))
Source: local data frame [4 x 3]
Groups: ref [?]
ref year max(csum)
(fctr) (int) (dbl)
1 A 2014 120
2 A 2015 80
3 B 2014 50
4 B 2015 90
与上面的 tapply 解决方案非常相似。不过,我发现 aggregate
的输出比 tapply
更好。
with(DF, aggregate(list(Value = values),list(Year = year,ref = ref), func))
Year ref Value
1 2014 A 120
2 2015 A 80
3 2014 B 60
4 2015 B 90
我有一个数据框,很像这个:
ref=rep(c("A","B"),each=240)
year=rep(rep(2014:2015,each=120),2)
month=rep(rep(1:12,each=10),4)
values=c(rep(NA,200),rnorm(100,2,1),rep(NA,50),rnorm(40,4,2),rep(NA,90))
DF=data.frame(ref,year,month,values)
我想计算每年每个参考文献的最大连续 NA 数。 我创建了一个函数,它计算出连续NA的最大数量,但只能基于一个变量。
例如,
func <- function(x) {
max(rle(is.na(x))$lengths)
}
with(DF, tapply(values,ref, func))
# A B
# 200 90
with(DF, tapply(values,year, func))
# 2014 2015
# 120 90
所以在ref A中总共最多有200个连续的NA,在ref B中最多有90个,这是正确的。 2014年还有120个NA,2015年有90个
我想要的是每个 ref 和年份的结果,例如:
A 2015 80
A 2014 120
B 2015 90
B 2014 50
有多种方法可以做到这一点,一种是使用 plyr 库:
library(plyr)
ddply(DF,c('ref','year'),summarise,NAs=max(rle(is.na(values))$lengths))
ref year NAs
1 A 2014 120
2 A 2015 80
3 B 2014 60
4 B 2015 90
使用你的函数,你也可以试试:
with(DF, tapply(values,list(ref,year), func))
输出略有不同
2014 2015
A 120 80
B 60 90
通过使用 melt(),您可以获得相同的数据帧。
我喜欢食谱格式
library(dplyr)
DF$values[is.na(DF$values)] <- 1
DF %>%
filter(values==1) %>%
group_by(ref,year) %>%
mutate(csum=cumsum(values)) %>%
group_by(ref,year) %>%
summarise(max(csum))
Source: local data frame [4 x 3]
Groups: ref [?]
ref year max(csum)
(fctr) (int) (dbl)
1 A 2014 120
2 A 2015 80
3 B 2014 50
4 B 2015 90
与上面的 tapply 解决方案非常相似。不过,我发现 aggregate
的输出比 tapply
更好。
with(DF, aggregate(list(Value = values),list(Year = year,ref = ref), func))
Year ref Value
1 2014 A 120
2 2015 A 80
3 2014 B 60
4 2015 B 90