2015-04-29 10 views
7

Próbuję obliczyć kilka nowych zmiennych w mojej ramce danych. Przyjmować wartości początkowej na przykład:Lapply w ramce danych na różnych zmiennych przy użyciu filtrów

Say mam:

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 

I chcę:

 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 

więc zarówno czas i zmienne zmieniają się dla nowych zmiennych. Oto moja próba:

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

Który działa bezbłędnie, ale niczego nie daje. Chciałbym przypisać nazwy zmiennych w przykładzie (np. "Var1_1990") i natychmiast uczynić nowe zmienne częścią części danych. Chciałbym również uniknąć pętli for, ale nie wiem, jak zawijać dwie lapply wokół tej funkcji. Czy powinienem raczej użyć tej funkcji, używając dwóch argumentów? Czy problem polega na tym, że funkcja apply nie przenosi wyników do mojego środowiska? Utknąłem tu przez jakiś czas, więc będę wdzięczny za każdą pomoc!

ps: Mam rozwiązanie, aby zrobić to połączenie przez kombinacje bez zastosowania i lubi ale staram się uciec od kopiowania i wklejania:

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

Odpowiedz

4

To można zrobić z subset(), reshape(), i 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 

kolejność kolumna nie jest dokładnie to, co masz w swoim pytaniu, ale można naprawić, że nawet po-fakt, ze operacji indeksu, jeśli to konieczne.

1

Z dplyr i tidyr i za pomocą funkcji niestandardowych spróbuj wykonać następujące czynności:

danych

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

Kod

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

Oto data.table Metoda:

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 

Zakłada się, że zmienna time są identyczne (oraz w tej samej kolejności) dla każdej wartości geo.

Powiązane problemy