2015-04-29 10 views
7

Ich versuche, mehrere neue Variablen in meinem Datenrahmen zu berechnen. Nehmen Sie Anfangswerte zum Beispiel:Lapply in einem Datenrahmen über verschiedene Variablen mit Filtern

Sagen, ich habe:

Dataset <- data.frame(time=rep(c(1990:1992),2), 
      geo=c(rep("AT",3),rep("DE",3)),var1=c(1:6), var2=c(7:12)) 

     time geo var1 var2 
1  1990 AT 1 7 
2  1991 AT 2 8 
3  1992 AT 3 9 
4  1990 DE 4 10 
5  1991 DE 5 11 
6  1992 DE 6 12 

Und ich will:

 time geo var1 var2 var1_1990 var1_1991 var2_1990 var2_1991 
1  1990 AT 1  7  1   2   7   8 
2  1991 AT 2  8  1   2   7   8 
3  1992 AT 3  9  1   2   7   8 
4  1990 DE 4  10  4   5   10  11 
5  1991 DE 5  11  4   5   10  11 
6  1992 DE 6  12  4   5   10  11 

So sowohl Zeit als auch die Variable für die neuen Variablen ändern. Hier ist mein Versuch:

intitialyears <- c(1990,1991) 
intitialvars <- c("var1", "var2") 
# ideally, I want code where I only have to change these two vectors 
# and where it's possible to change their dimensions 

for (i in initialyears){ 
lapply(initialvars,function(x){ 
rep(Dataset[time==i,x],each=length(unique(Dataset$time))) 
})} 

Das läuft ohne Fehler aber ergibt nichts. Ich würde die Variablennamen im Beispiel (z. B. "var1_1990") zuweisen und die neuen Variablen sofort in den Datenrahmen einfügen. Ich möchte auch die for-Schleife vermeiden, aber ich weiß nicht, wie man zwei Pakete um diese Funktion wickelt. Soll ich die Funktion lieber zwei Argumente verwenden? Liegt das Problem vor, dass die Apply-Funktion die Ergebnisse nicht in meine Umgebung überträgt? Ich bin hier für eine Weile festgefahren, also wäre ich dankbar für jede Hilfe!

ps: Ich habe die Lösung diese Kombination durch Kombination zu tun, ohne anwenden und die Gleichen, aber ich versuche von Kopieren und Einfügen wegzukommen:

Dataset$var1_1990 <- c(rep(Dataset$var1[which(Dataset$time==1990)], 
         each=length(unique(Dataset$time)))) 

Antwort

4

Das mit subset() getan werden kann, reshape(), und merge():

merge(Dataset,reshape(subset(Dataset,time%in%c(1990,1991)),dir='w',idvar='geo',sep='_')); 
## geo time var1 var2 var1_1990 var2_1990 var1_1991 var2_1991 
## 1 AT 1990 1 7   1   7   2   8 
## 2 AT 1991 2 8   1   7   2   8 
## 3 AT 1992 3 9   1   7   2   8 
## 4 DE 1990 4 10   4  10   5  11 
## 5 DE 1991 5 11   4  10   5  11 
## 6 DE 1992 6 12   4  10   5  11 

die Spaltenreihenfolge ist nicht genau das, was Sie in Ihrer Frage haben, aber Sie können diese bis nach-der-Tat mit einer Index-Operation beheben, falls erforderlich.

1

Mit dplyr und tidyr und mit einem benutzerdefinierten Funktion versuchen Sie folgendes:

Daten

Dataset <- data.frame(time=rep(c(1990:1992),2), 
      geo=c(rep("AT",3),rep("DE",3)),var1=c(1:6), var2=c(7:12)) 

-Code

library(dplyr); library(tidyr) 

intitialyears <- c(1990,1991) 
intitialvars <- c("var1", "var2") 

#create this function 
myTranForm <- function(dataSet, varName, years){ 

    temp <- dataSet %>% select(time, geo, eval(parse(text=varName))) %>% 
      filter(time %in% years) %>% mutate(time=paste(varName, time, sep="_")) 

    names(temp)[names(temp) %in% varName] <- "someRandomStringForVariableName" 
    temp <- temp %>% spread(time, someRandomStringForVariableName) 
    return(temp) 
} 

#Then lapply on intitialvars using the custom function 
DatasetList <- lapply(intitialvars, function(x) myTranForm(Dataset, x, intitialyears)) 

#and loop over the data frames in the list 
for(i in 1:length(intitialvars)){ 
    Dataset <- left_join(Dataset, DatasetList[[i]]) 
} 

Dataset 
2

Hier ist eine data.table Methode:

require(data.table) 
dt <- as.data.table(Dataset) 
in_cols = c("var1", "var2") 
out_cols = do.call("paste", c(CJ(in_cols, unique(dt$time)), sep="_")) 

dt[, (out_cols) := unlist(lapply(.SD, as.list), FALSE), by=geo, .SDcols=in_cols] 

# time geo var1 var2 var1_1990 var1_1991 var1_1992 var2_1990 var2_1991 var2_1992 
# 1: 1990 AT 1 7   1   2   3   7   8   9 
# 2: 1991 AT 2 8   1   2   3   7   8   9 
# 3: 1992 AT 3 9   1   2   3   7   8   9 
# 4: 1990 DE 4 10   4   5   6  10  11  12 
# 5: 1991 DE 5 11   4   5   6  10  11  12 
# 6: 1992 DE 6 12   4   5   6  10  11  12 

Dies setzt voraus, dass der variable time identisch ist (und in der gleichen Reihenfolge) für jeden Wert geo.