2016-07-09 10 views
2

Ich habe zwei Fragen: Welche Ressourcen empfehlen Sie zu lesen, um Datenmanipulationsfunktionen zu verbessern? Ich habe mit größeren Datensätzen gearbeitet und habe mich mühsam angepasst - ich fühle mich, als würde ich gegen eine Wand stoßen und weiß nicht, wo ich hinschauen soll (viele Online-Ressourcen werden zu kompliziert, ohne die Grundlage zu schaffen).Vereinfachen Sie den Datenrahmen pro Jahr und berechnen Sie die prozentuale Änderung

Zum Beispiel versuche ich, dieses Problem zu lösen. Ich habe ein df mit Millionen von Zeilen und ich versuche es zu vereinfachen und einen Trend zu analysieren. Ich habe ein Beispiel dafür. Ich versuche, jede ID zu isolieren und den Mindestwert für ein bestimmtes Jahr zu erfassen. (Einige IDs sind für andere Jahre nicht verfügbar). Nachdem ich diese Daten vereinfacht habe, versuche ich eine Spalte für die prozentuale Änderung hinzuzufügen. Wenn man bedenkt, dass es eine Zeitreihe von mehr als 20 Jahren gibt, dann bin ich damit einverstanden, Monate an diesem Punkt zu ignorieren, da ein Mindestwert für ein Jahr gegenüber einem Minimum für ein anderes Jahr eine angemessene prozentuale Veränderung ergeben sollte.

Danke!

Eingang:

structure(list(ID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L), .Label = c("a", "b"), class = "factor"), Date = structure(c(1L, 
2L, 3L, 4L, 5L, 6L, 10L, 12L, 14L, 7L, 8L, 9L, 11L, 13L, 5L, 
6L, 10L, 12L, 14L, 7L, 8L, 9L, 11L, 13L, 15L, 16L), .Label = c("2/21/2009", 
"2/22/2009", "2/23/2009", "2/24/2009", "2/25/2009", "2/26/2009", 
"3/2/2011", "3/3/2011", "3/4/2011", "3/5/2010", "3/5/2011", "3/6/2010", 
"3/6/2011", "3/7/2010", "3/7/2011", "3/8/2011"), class = "factor"), 
    Year = c(2009L, 2009L, 2009L, 2009L, 2009L, 2009L, 2010L, 
    2010L, 2010L, 2011L, 2011L, 2011L, 2011L, 2011L, 2009L, 2009L, 
    2010L, 2010L, 2010L, 2011L, 2011L, 2011L, 2011L, 2011L, 2011L, 
    2011L), Value = c(10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 
    20, 21, 22, 5, 6, 7, 8, 8, 9, 10, 11, 12, 15, 23, 25, 27)), .Names = c("ID", 
"Date", "Year", "Value"), class = "data.frame", row.names = c(NA, 
-26L)) 

Erwartete Ausgabe:

structure(list(ID = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("a", 
"b"), class = "factor"), Date = structure(c(1L, 4L, 5L, 2L, 4L, 
3L), .Label = c("2/21/2009", "2/25/2009", "3/2/2011", "3/5/2010", 
"3/6/2011"), class = "factor"), Year = c(2009L, 2010L, 2011L, 
2009L, 2010L, 2011L), Value = c(10, 16, 5, 6, 8, 10), Percent.Increase = c(NA, 
0.6, -0.6875, NA, 0.333333333, 0.25)), .Names = c("ID", "Date", 
"Year", "Value", "Percent.Increase"), class = "data.frame", row.names = c(NA, 
-6L)) 
+1

Soweit, was die data.table Vignetten zu lesen geht, ein guter Anfang sind: https://github.com/Rdatatable/data.table/wiki/Getting-started Für Anleitung, wie man über das Organisieren von Daten denkt, würde ich Hadleys Artikel https://www.jstatsoft.org/article/view/v059i10 empfehlen, obwohl er die Syntax von data.table nicht verwendet. – Frank

Antwort

3

Nach Gruppierung von 'ID', 'Jahr', wir slice die min "Value" Reihen innerhalb jeder Gruppe, dann gruppiert nach ' ID ', erstellen wir die' Percent.Increase 'durch Subtrahieren des' Value 'von lag von' Value 'und dividieren durch die lag von' Value '.

res <- df1 %>% 
     group_by(ID, Year) %>% 
     slice(which.min(Value)) %>% 
     group_by(ID) %>% 
     mutate(Percent.Increase = (Value-lag(Value))/lag(Value)) 
+0

Es ist verrückt, wie einfach du das machst. Danke @akrun! Empfehlen Sie eine bestimmte Ressource/Methode, um dplyr zu lernen? – sammyramz

+1

@sammyramz Ich denke, der beste Weg zu verstehen wäre zu üben, Fehler zu begehen, daraus zu lernen und natürlich die offizielle Dokumentation zu lesen. – akrun

2

Bis HAVING clause in data.table implementiert ist, scheint dies ziemlich effizient zu sein:

dt[dt[, .I[which.min(Value)],, .(ID, Year)]$V1 
    ][, Percent_Increase := { 
     tmp <- shift(Value) 
     (Value-tmp)/tmp 
    }, .(ID)] 

prüfen Timing auf 5E7.

library(dplyr) 
library(data.table) 
N = 5e7 
set.seed(1) 
df = data.frame(ID = sample(2L, N, TRUE), 
       Date = sample(16L, N, TRUE), 
       Year = sample(2009:2011, N, TRUE), 
       Value = sample(N/10, N, TRUE)) 
dt = as.data.table(df) 
system.time(
    res <- df %>% 
     group_by(ID, Year) %>% 
     slice(which.min(Value)) %>% 
     group_by(ID) %>% 
     mutate(Percent_Increase = (Value-lag(Value))/lag(Value))  
) 
# user system elapsed 
# 1.676 2.176 3.847 
system.time(
    r <- dt[dt[, .I[which.min(Value)],, .(ID, Year)]$V1, 
      ][, Percent_Increase := { 
       tmp <- shift(Value) 
       (Value-tmp)/tmp 
      }, .(ID)] 
) 
# user system elapsed 
# 0.940 0.460 1.334 
all.equal(r, as.data.table(res), ignore.col.order = TRUE, check.attributes = FALSE, ignore.row.order = TRUE) 
#[1] TRUE 
Verwandte Themen