2015-01-08 9 views
6

Ich entwickle ein Modell, das die Fertilität für eine Alterskohorte prognostiziert. Ich habe derzeit einen Datenrahmen wie diesen, in dem die Zeilen Alter und die Spalten Jahre sind. Der Wert in jeder Zelle ist altersspezifischen Geburten für dieses Jahr:In R, Datenrahmen Diagonalen in Zeilen konvertieren

> df1 
    iso3 sex age fert1953 fert1954 fert1955 
14 AUS female 13 0.000 0.00000 0.00000 
15 AUS female 14 0.000 0.00000 0.00000 
16 AUS female 15 13.108 13.42733 13.74667 
17 AUS female 16 26.216 26.85467 27.49333 
18 AUS female 17 39.324 40.28200 41.24000 

Doch was ich will, ist jede Zeile eine Kohorte zu sein. Da die Zeilen und Spalten einzelne Jahre darstellen, können die Kohorten-Daten erhalten werden, indem die Diagonale erhalten wird. Ich suche ein Ergebnis wie folgt aus:

> df2 
    iso3 sex ageIn1953 fert1953 fert1954 fert1955 
14 AUS female  13 0.000 0.00000 13.74667 
15 AUS female  14 0.000 13.42733 27.49333 
16 AUS female  15 13.108 26.85467 41.24000 
17 AUS female  16 26.216 40.28200 [data..] 
18 AUS female  17 39.324 [data..] [data..] 

Hier ist die df1 Datenrahmen:

df1 <- structure(list(iso3 = c("AUS", "AUS", "AUS", "AUS", "AUS"), sex = c("female", 
"female", "female", "female", "female"), age = c(13, 14, 15, 
16, 17), fert1953 = c(0, 0, 13.108, 26.216, 39.324), fert1954 = c(0, 
0, 13.4273333333333, 26.8546666666667, 40.282), fert1955 = c(0, 
0, 13.7466666666667, 27.4933333333333, 41.24)), .Names = c("iso3", 
"sex", "age", "fert1953", "fert1954", "fert1955"), class = "data.frame", row.names = 14:18) 

EDIT:

Hier ist die Lösung, die ich letztlich verwendet. Es basiert auf Davids Antwort, aber ich musste dies für jedes Level von iso3 tun.

df.ls <- lapply(split(f3, f = f3$iso3), FUN = function(df1) { 
    n <- ncol(df1) - 4 
    temp <- mapply(function(x, y) lead(x, n = y), df1[, -seq_len(4)], seq_len(n)) 
    return(cbind(df1[seq_len(4)], temp)) 
}) 
f4 <- do.call("rbind", df.ls) 
+0

Haben Sie einfach hinken wollen Datensatz? –

+0

Ja, aber ich denke, das wäre sehr umständlich. Ich mache das für 188 Länder über 50 Jahre. Wenn Sie sich einen guten Weg vorstellen können, könnte das eine gute Lösung sein. – rsoren

Antwort

4

ich nicht auf Geschwindigkeit getestet haben, aber data.tablev1.9.5, vor kurzem eine neue (geschrieben in C) umgesetzt Führungs-/Verzögerungsfunktion genannt shift

also die Spalten, die Sie verschieben möchten, könnten Sie möglicherweise verwenden Sie es mit mapply kombiniert, zum Beispiel

library(data.table) 
n <- ncol(df1) - 4 # the number of years - 1 
temp <- mapply(function(x, y) shift(x, n = y, type = "lead"), df1[, -seq_len(4)], seq_len(n)) 
cbind(df1[seq_len(4)], temp) # combining back with the unchanged columns 
# iso3 sex age fert1953 fert1954 fert1955 
# 14 AUS female 13 0.000 0.00000 13.74667 
# 15 AUS female 14 0.000 13.42733 27.49333 
# 16 AUS female 15 13.108 26.85467 41.24000 
# 17 AUS female 16 26.216 40.28200  NA 
# 18 AUS female 17 39.324  NA  NA 

Edit: Sie können die Entwicklung einfach installieren Version von data.table von GitHub

library(devtools) 
install_github("Rdatatable/data.table", build_vignettes = FALSE) 

So oder so verwenden, wenn Sie dplyr möchten, hier geht

library(dplyr) 
n <- ncol(df1) - 4 # the number of years - 1 
temp <- mapply(function(x, y) lead(x, n = y), df1[, -seq_len(4)], seq_len(n)) 
cbind(df1[seq_len(4)], temp) 
# iso3 sex age fert1953 fert1954 fert1955 
# 14 AUS female 13 0.000 0.00000 13.74667 
# 15 AUS female 14 0.000 13.42733 27.49333 
# 16 AUS female 15 13.108 26.85467 41.24000 
# 17 AUS female 16 26.216 40.28200  NA 
# 18 AUS female 17 39.324  NA  NA 
+0

Das sieht gut aus. Leider ist v1.9.4 die neueste Version von data.table auf CRAN, und ich habe Probleme beim Herunterladen der dev Version von GitHub. Anscheinend ist dies ein häufiges Problem unter Windows. Ich arbeite stattdessen an der '' '' '' '- Funktion von dplyr' '' Ich denke, es sollte funktionieren ... – rsoren

+0

Siehe meine Bearbeitung dann –

+0

Ich habe eine Anpassung vorgenommen, um die Tatsache zu berücksichtigen, dass dies separat für jeden Wert von '' 'iso3''' durchgeführt werden muss (siehe meine Bearbeitung oben). Das Problem mit data.table war, dass ich einen "Command failed (1)" Fehler bekommen habe, was es schwieriger gemacht hat als das übliche '' 'install_github()' ''. Es gibt einen Link dazu auf der Installationsseite von data.table. Vielen Dank! – rsoren

1

ist hier ein Basis R Ansatz:

df1[,5:ncol(df1)] <- mapply(function(x, y) {vec.list <- df1[-1:-y, x] 
         length(vec.list) <- nrow(df1) 
         vec.list}, 
         x=5:ncol(df1), y=1:(ncol(df1)-4)) 
df1 
# iso3 sex age fert1953 fert1954 fert1955 
#14 AUS female 13 0.000 0.00000 13.74667 
#15 AUS female 14 0.000 13.42733 27.49333 
#16 AUS female 15 13.108 26.85467 41.24000 
#17 AUS female 16 26.216 40.28200  NA 
#18 AUS female 17 39.324  NA  NA