2016-06-16 19 views
2

Lasst uns sagen, dass ich einen Datenrahmen, die wie diesesR: Erstellen Sie mehrere neue Spalten basiert auf anderen Spalten

dd <- read.table(header = TRUE, text = "ID week1_t week1_a week2_t week2_a 
    1  12  22  17  4 
    1  15  32  18  5 
    1  24  12  29  6 
    2  45  11  19  8 
    2  23  33  20  10") 

sieht Gibt es eine einfache Möglichkeit, eine week1_d Säule, eine week2_d Spalte, und so weiter zu erstellen für jede Woche, die auf dem Unterschied zwischen week1_t und week1_a basiert? Oder muss ich die Spalten "Differenz" manuell erstellen?

Erwartete Ausgabe sieht wie folgt aus:

dd <- read.table(header = TRUE, text = "ID week1_t week1_a week2_t week2_a week1_d week2_d 
    1  12  22  17  4  10  -13     
    1  15  32  18  5  17  -13 
    1  24  12  29  6  -12  -23 
    2  45  11  19  8  -34  -11 
    2  23  33  20  10  10  -10  ") 

In Wirklichkeit gibt es rund 30 Wochen, also versuche ich, von Hand zu vermeiden, dies zu tun. Ich dachte an eine For-Schleife, die jede Woche durchläuft, und Spalten, die der Woche + (Index der Schleife) entsprechen. Gibt es einen besseren Weg, dies zu tun?

Antwort

5

Von einem „sauberen Daten "Perspektive, Ihr Problem ist, dass Sie (mehrere!) Daten in Ihren Spaltennamen kodieren: die Wochennummer und was auch immer der Buchstabe steht. Ich würde in ein langes Format umwandeln, in dem Woche eine Spalte ist, d = a - t definieren und (wenn notwendig) zurück in Wide-Format konvertieren. Aber wahrscheinlich würde ich es im langen Format behalten, denn wenn Sie irgendwelche anderen Operationen durchführen möchten, werden sie wahrscheinlich leichter auf den langen Daten zu implementieren sein (mehr Manipulation, Modellierung, Plotten ...).

library(tidyr) 
library(dplyr) 

long = dd %>% 
    mutate(real_id = 1:n()) %>% 
    gather(key = key, value = value, starts_with("week")) %>% 
    separate(key, into = c("week", "letter")) %>% 
    spread(key = letter, value = value) %>% 
    mutate(d = a - t) 

head(long) 
# ID real_id week a t d 
# 1 1  1 week1 22 12 10 
# 2 1  1 week2 4 17 -13 
# 3 1  2 week1 32 15 17 
# 4 1  2 week2 5 18 -13 
# 5 1  3 week1 12 24 -12 
# 6 1  3 week2 6 29 -23 

wide = gather(long, key = letter, value = value, a, t, d) %>% 
    mutate(key = paste(week, letter, sep = "_")) %>% 
    select(-week, -letter) %>% 
    spread(key = key, value = value) 

wide 
# ID real_id week1_a week1_d week1_t week2_a week2_d week2_t 
# 1 1  1  22  10  12  4  -13  17 
# 2 1  2  32  17  15  5  -13  18 
# 3 1  3  12  -12  24  6  -23  29 
# 4 2  4  11  -34  45  8  -11  19 
# 5 2  5  33  10  23  10  -10  20 
+0

Große Antwort! Danke, Gregor. – Parseltongue

+0

@Gregor große Antwort – nik

3

Wir split die ‚Woche‘ Spalten (dd[-1]) durch die names des Datensatzes nach dem Suffix mit sub in eine list entfernen, erhalten die Differenz zwischen den beiden Spalten und weisen Sie die list Elemente neue Spalten in ‚dd‘ erstellen .

lst <- lapply(split.default(dd[-1], 
      sub("_.*", "", names(dd)[-1])), function(x) x[2]-x[1]) 
dd[paste0("week_", seq_along(lst), "d")] <- lapply(lst, unlist, use.names=FALSE) 
dd 
# ID week1_t week1_a week2_t week2_a week1_d week2_d 
#1 1  12  22  17  4  10  -13 
#2 1  15  32  18  5  17  -13 
#3 1  24  12  29  6  -12  -23 
#4 2  45  11  19  8  -34  -11 
#5 2  23  33  20  10  10  -10 

Wenn die Spalten abwechselnd dh 'week1_t', gefolgt von 'week1_a', dann 'week2_t', gefolgt von 'week2_a' usw.

Un1 <- unique(sub("_.*", "", names(dd)[-1])) 
i1 <- c(TRUE, FALSE) 
dd[paste0(Un1, "_d")] <- dd[-1][!i1]- dd[-1][i1] 
dd 
# ID week1_t week1_a week2_t week2_a week1_d week2_d 
#1 1  12  22  17  4  10  -13 
#2 1  15  32  18  5  17  -13 
#3 1  24  12  29  6  -12  -23 
#4 2  45  11  19  8  -34  -11 
#5 2  23  33  20  10  10  -10 
+0

@Parseltongue Es ist aktualisiert. Bitte überprüfen Sie, ob das hilft – akrun

+0

Hmm. Ich bin mir nicht sicher, was genau der Code macht. Was ist der Zweck dieses ersten geteilten Befehls? Ich erhalte den folgenden Fehler: https://i.imgur.com/JDe1qYM.png – Parseltongue

+0

@Parseltongue Dies basiert nur auf dem von Ihnen gezeigten Beispiel. Für mich geht das. BTW, hier verwende ich nur "Base R" -Funktionen. – akrun

Verwandte Themen