2012-05-14 9 views
14

mam kod, R, który wykonuje pewną operację uzyskiwania danych o wszystkich plikach w katalogu bieżącym zastosowaniem kodu:Wyodrębnianie wyjść z lapply do dataframe

files <- list.files(".", pattern="*.tts") 
results <- lapply(files, data_for_time, "17/06/2006 12:00:00") 

Wyjście z lapply jest następujący (wyodrębnione stosując dput()) - w zasadzie lista pełna wektorów:

list(c("amer", "14.5"), c("appl", "14.2"), c("brec", "13.1"), 
c("camb", "13.5"), c("camo", "30.1"), c("cari", "13.8"), 
c("chio", "21.1"), c("dung", "9.4"), c("east", "11.8"), c("exmo", 
"12.1"), c("farb", "14.7"), c("hard", "15.6"), c("herm", 
"24.3"), c("hero", "13.3"), c("hert", "11.8"), c("hung", 
"26"), c("lizr", "14"), c("maid", "30.4"), c("mart", "8.8" 
), c("newb", "14.7"), c("newl", "14.3"), c("oxfr", "13.9" 
), c("padt", "10.3"), c("pbil", "13.6"), c("pmtg", "11.1" 
), c("pmth", "11.7"), c("pool", "14.6"), c("prae", "11.9" 
), c("ral2", "12.2"), c("sano", "15.3"), c("scil", "36.2" 
), c("sham", "12.9"), c("stra", "30.9"), c("stro", "14.7" 
), c("taut", "13.7"), c("tedd", "22.3"), c("wari", "12.7" 
), c("weiw", "13.6"), c("weyb", "8.4")) 

jednak chciałbym wtedy do czynienia z tego wyjścia jako dataframe z dwóch kolumn: jeden dla kodu alfabetycznego ("amer", "appl" etc) oraz jeden dla t on numer (14.5, 14.2 itp.).

Niestety, as.data.frame wydaje się nie działać z tym wejściem zagnieżdżonych wektorów wewnątrz listy. Jak mam to zmienić? Czy muszę zmienić sposób, w jaki moja funkcja data_for_time zwraca swoje wartości? W tej chwili po prostu zwraca c(name, value). Czy istnieje dobry sposób konwertowania z tego rodzaju danych wyjściowych na ramkę danych?

+1

Jeśli użył 'sapply' zamiast' lapply' mogłeś zdobyć więcej „zwykłej” obiektu. –

Odpowiedz

8

Jedną opcją może być użycie funkcji ldply z pakietu plyr, która połączy elementy z powrotem w ramkę danych.

trywialny przykład na jego zastosowanie:

ldply(1:10,.fun = function(x){c(runif(1),"a")}) 
        V1 V2 
1 0.406373084755614 a 
2 0.456838687881827 a 
3 0.681300171650946 a 
4 0.294320539338514 a 
5 0.811559669673443 a 
6 0.340881009353325 a 
7 0.134072444401681 a 
8 0.00850683846510947 a 
9 0.326008745934814 a 
10 0.90791508089751 a 

Należy jednak pamiętać, że jeśli mieszanie typy zmiennych z c(), prawdopodobnie będzie chcą zmienić swoją funkcję, aby powrócić po prostu data.frame(name= name,value = value) zamiast c(name,value). W przeciwnym razie wszystko zostanie przymuszone do postaci (tak jak w moim przykładzie powyżej).

28

Spróbuj tego jeśli results były lista:

> as.data.frame(do.call(rbind, results)) 

    V1 V2 
1 amer 14.5 
2 appl 14.2 
3 brec 13.1 
4 camb 13.5 
... 
+4

+1 - "do.call" jest tutaj elegancka. Poleciłbym nawet, aby OP zmienił jego funkcję 'data_for_time', aby zwrócić data.frame z odpowiednimi nazwami i typami. Aby usunąć tutaj wywołanie 'as.data.frame' i ryzyko przymusu. – flodel

1

Bo i forNelton wziął odpowiedź byłem w procesie dawania i Joran wziął tylko inną racjonalną odpowiedź mogłem pomyśleć, a ponieważ mam do pisania tutaj referat to śmieszne odpowiedź:

#I named your list LIST 
LIST2 <- LIST[[1]] 
lapply(2:length(LIST), function(i) {LIST2 <<- rbind(LIST2, LIST[[i]])}) 
data.frame(LIST2) 
3
inp <- list(c("amer", "14.5"), c("appl", "14.2"), .... # did not see need to copy all 

data.frame(first= sapply(inp, "[", 1), 
      second =as.numeric(sapply(inp, "[", 2))) 

    first second 
1 amer 14.5 
2 appl 14.2 
3 brec 13.1 
4 camb 13.5 
5 camo 30.1 
6 cari 13.8 
snipped output