2014-11-03 8 views
5

Jestem bardzo nowy w R i szukam sposobów odtwarzania makra programu Excel VBA i funkcji arkusza programu Excel, takich jak SUMA.JEŻELI. SUMA.JEŻELI sumuje kolumnę, jeśli wiersz zawiera wpisy pasujące do wielu warunków w innych kolumnach.Równoważnik programu Excel SUMIFS w R

Mam poniżej ramki danych i chcę obliczyć nową kolumnę. Nowa kolumna jest sumą Sample dla wszystkich wierszy, które pokrywają się z zakresem Start Date i EndDate. Na przykład w linii 1 będzie to 697 (suma pierwszego 3 lines). Kryteria sumy obejmują w szczególności: Sample jeśli EndDate >= StartDate[i] & StartDate <=EndDate[i]

StartDate EndDate Sample *SUMIFS example* 
10/01/14 24/01/14 139   *697* 
12/01/14 26/01/14 136 
19/01/14 02/02/14 422 
25/01/14 08/02/14 762 
29/01/14 12/02/14 899 
05/02/14 19/02/14 850 
07/02/14 21/02/14 602 
09/02/14 23/02/14 180 
18/02/14 04/03/14 866 

Wszelkie komentarze lub wskazówki będą bardzo mile widziane.

Odpowiedz

2

Zakładając, że powyższe dane w ramce danych zwanych df:

sum(df$Sample[EndDate >= df$StartDate & StartDate <= df$EndDate]) 

Czyli:

  • df$Sample[...] wybiera kolumnę Sample z warunkami określonymi w [...]
  • EndDate >= df$StartDate i StartDate <= df$EndDate są z twojego przykładu, konwertowane na warunki R, z & pomiędzy wymagać, aby oba warunki były prawdziwe w tym samym czasie. Zauważ, że nie ma indeksów i w wyrażeniu. Tak to działa w R, wyrażenie jest obliczane dla każdego wiersza w ramce danych, a wynik df$Sample[...] jest wektorem wartości, a jedynie wartości, w których wyrażenie w [...] było prawdziwe, jest oczywiście wbudowane. w funkcji do obliczenia sumy, oczywiście
+0

to nie daje tego, co chciał OP, dla każdego wiersza chciał patrzeć na wszystkich innych wierszy i podsumować kolumnę próbki, jeżeli spełnia kryteria . –

+0

Dziękuję bardzo, ale jak wspomniał Cameron, nie robi to dokładnie tego, na co liczyłem (choć doskonale to podsumowuje). Doceniam pomoc. – Barnaby1

3

Można to zrobić za pomocą pętli lub z łączeniem kartezjańskim. Nie znam żadnych wbudowanych funkcji, aby to dokładnie zrobić.

library(dplyr) 

x = structure(list(StartDate = structure(c(1389312000, 1389484800, 
1390089600, 1390608000, 1390953600, 1391558400, 1391731200, 1391904000, 
1392681600), tzone = "UTC", class = c("POSIXct", "POSIXt")), 
    EndDate = structure(c(1390521600, 1390694400, 1391299200, 
    1391817600, 1392163200, 1392768000, 1392940800, 1393113600, 
    1393891200), tzone = "UTC", class = c("POSIXct", "POSIXt" 
    )), Sample = c(139L, 136L, 422L, 762L, 899L, 850L, 602L, 
    180L, 866L)), .Names = c("StartDate", "EndDate", "Sample" 
), row.names = c(NA, -9L), class = "data.frame") 

x2 = x 
names(x2)=c('StartDate2','EndDate2','Sample2') 
x3 = merge(x,x2,allow.cartesian =T) 
x4 = summarise(group_by(x3,StartDate,EndDate), 
    sumifs=sum(Sample2[EndDate2 >= StartDate & StartDate2 <= EndDate])) 
x_sumifs = merge(x,x4,by=c('StartDate','EndDate')) 

Tak wygląda wyjście.

> x_sumifs 
    StartDate EndDate Sample sumifs 
1 2014-01-10 2014-01-24 139 697 
2 2014-01-12 2014-01-26 136 1459 
3 2014-01-19 2014-02-02 422 2358 
4 2014-01-25 2014-02-08 762 3671 
5 2014-01-29 2014-02-12 899 3715 
6 2014-02-05 2014-02-19 850 4159 
7 2014-02-07 2014-02-21 602 4159 
8 2014-02-09 2014-02-23 180 3397 
9 2014-02-18 2014-03-04 866 2498 
2

Można użyć lapply/sapply z base R to zrobić. x z wpisu @ cameron.bracken.

x$sumifs <- sapply(seq_len(nrow(x)), function(i) with(x, 
      sum(Sample[EndDate >= StartDate[i] & StartDate <= EndDate[i]]))) 

x 
# StartDate EndDate Sample sumifs 
#1 2014-01-10 2014-01-24 139 697 
#2 2014-01-12 2014-01-26 136 1459 
#3 2014-01-19 2014-02-02 422 2358 
#4 2014-01-25 2014-02-08 762 3671 
#5 2014-01-29 2014-02-12 899 3715 
#6 2014-02-05 2014-02-19 850 4159 
#7 2014-02-07 2014-02-21 602 4159 
#8 2014-02-09 2014-02-23 180 3397 
#9 2014-02-18 2014-03-04 866 2498 
0

Możesz użyć funkcji "by", aby uzyskać wartość. W ramce danych "od" jest dzielona przez rząd na ramki danych podzielone przez wartości jednego lub więcej czynników, a funkcja jest stosowana do każdego podzestawu po kolei.

x$sumifs <- by(Sample[EndDate >= StartDate[i] & StartDate <= EndDate[i]],sum) 

Więcej szczegółów na temat tej funkcji można znaleźć here

Powiązane problemy