2015-04-29 15 views
7

Sto provando a calcolare diverse nuove variabili nel mio dataframe. Prendere valori iniziali per esempio:Lapply in un dataframe su diverse variabili utilizzando i filtri

Dire che ho:

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 

E voglio:

 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 

Così sia il tempo e la variabile stanno cambiando per le nuove variabili. Ecco il mio tentativo:

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))) 
})} 

Che funziona senza errori ma non produce nulla. Vorrei assegnare i nomi delle variabili nell'esempio (ad esempio "var1_1990") e rendere immediatamente le nuove variabili parte del dataframe. Vorrei anche evitare il ciclo for, ma non so come avvolgere due lappie attorno a questa funzione. Dovrei preferire che la funzione usi due argomenti? Il problema è che la funzione apply non porta i risultati nel mio ambiente? Sono stato bloccato qui per un po 'quindi sarei grato per qualsiasi aiuto!

ps: ho la soluzione per fare questa combinazione per combinazione, senza applicare e del calibro, ma sto cercando di allontanarsi da copia e incolla:

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

risposta

4

Questo può essere fatto con subset(), reshape(), e 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 

l'ordine delle colonne non è esattamente quello che hai nella tua domanda, ma si può rimediare dopo-il-fatto con un'operazione di indice, se necessario.

1

Con dplyr e tidyr e utilizzando una funzione personalizzata provare quanto segue:

dati

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)) 

Codice

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

Ecco un metodo data.table:

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 

Questo presuppone che la variabile time è identico (e nello stesso ordine) per ogni valore geo.

Problemi correlati