2016-04-22 18 views
0

Ich habe einen Datenrahmen, ähnlich wie diese:tapply basierend auf mehreren Indizes 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) 

Ich mag die maximale Anzahl aufeinander folgenden NAs pro Bezug zu berechnen, pro Jahr. Ich habe eine Funktion erstellt, die die maximale Anzahl aufeinanderfolgender NAs ermittelt, aber nur auf einer Variablen basieren kann.

Zum Beispiel

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 

So gibt es ein Maximum von 200 aufeinanderfolgenden NAs in Ref A insgesamt maximal 90 und in Ref B, die korrekt ist. Darüber hinaus gibt es 120 NAs im Jahr 2014 und 90 im Jahr 2015.

Was würde Ich mag ein Ergebnis pro ref ist und Jahr, wie zum Beispiel:

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

Antwort

1

Es gibt mehrere Möglichkeiten, dies zu tun, ist eine mit der plyr Bibliothek:

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 

Ihre Funktion verwenden, können Sie auch versuchen:

with(DF, tapply(values,list(ref,year), func)) 

, die ein leicht verschie gibt Mietausgang

2014 2015 
A 120 80 
B 60 90 

Durch die Verwendung von schmelzen() können Sie jedoch auf den gleichen Datenrahmen gelangen.

+0

Das ist genau das, was ich will. Vielen Dank! – sym246

0

Ich mag das Rezept Format

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

Sehr ähnlich die tapply Lösung oben. Ich finde aggregate geben eine bessere Ausgabe als tapply obwohl.

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 
Verwandte Themen