2016-04-22 4 views
0

У меня есть кадр данных, так же, как этот:tapply на основе нескольких индексов в 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, но может быть основана только на одной переменной.

Например,

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 

Таким образом, есть максимум 200 последовательных ВПЛ в работе А в общей сложности, и максимум 90 в исх B, который является правильным. Есть также 120 NAs в 2014 году и 90 в 2015 году

То, что я хотел бы это результат за исх и год, например:

A 2015 80 
A 2014 120 
B 2015 90 
B 2014 50 

ответ

1

Есть несколько способов сделать это, один является с библиотекой 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 

Используя расплав(), вы можете, однако, добраться до того же кадра данных.

+0

Это именно то, что я хочу. Благодаря! – sym246

0

мне нравится формат рецепта

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 
1

очень похож на 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