2012-05-14 34 views
14

Tôi có một số mã R mà thực hiện một số hoạt động khai thác dữ liệu trên tất cả các file trong thư mục hiện hành, sử dụng đoạn mã sau:Trích xuất đầu ra từ lapply đến một dataframe

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

Kết quả từ lapply là như sau (trích sử dụng dput()) - cơ bản là một danh sách đầy đủ của các vectơ:

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

Tuy nhiên, tôi muốn sau đó đối phó với sản lượng này như một dataframe với hai cột: một cho mã chữ cái ("amer", "appl" vv) và một cho t anh ấy số (14.5, 14.2 v.v.).

Thật không may, as.data.frame dường như không hoạt động với đầu vào này của vectơ lồng nhau bên trong danh sách. Làm thế nào tôi nên đi về việc chuyển đổi này? Tôi có cần thay đổi cách chức năng của tôi data_for_time trả về giá trị của nó không? Hiện tại, nó chỉ trả lại c(name, value). Hoặc là có một cách tốt đẹp để chuyển đổi từ loại đầu ra đến một dataframe?

+1

Nếu bạn đã sử dụng 'sapply' thay vì lapply' bạn có thể đã nhận được một đối tượng' hơn "bình thường". –

Trả lời

8

Một tùy chọn có thể là sử dụng chức năng ldply từ gói plyr, thao tác này sẽ ghép mọi thứ trở lại vào khung dữ liệu cho bạn.

Một ví dụ tầm thường của nó là sử dụng:

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 

Nhưng lưu ý rằng nếu bạn đang trộn các loại biến với c(), có lẽ bạn sẽ muốn thay đổi chức năng của bạn để trở lại đơn giản data.frame(name= name,value = value) thay vì c(name,value). Nếu không, mọi thứ sẽ bị ép buộc vào ký tự (như trong ví dụ trên).

28

Hãy thử điều này nếu results là danh sách của bạn:

> 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' thanh lịch ở đây. Tôi thậm chí khuyên bạn nên OP sửa đổi hàm 'data_for_time' của mình để trả về một data.frame với các tên và kiểu thích hợp. Vì vậy, để loại bỏ các cuộc gọi 'as.data.frame' ở đây và nguy cơ cưỡng chế. – flodel

1

Vì và forNelton mất phản ứng tôi đang trong quá trình của việc cho và Joran mất chỉ phản ứng hợp lý khác tôi có thể nghĩ đến và kể từ khi tôi là nghĩa vụ được viết một bài báo đây là một câu trả lời vô lý:

#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 
Các vấn đề liên quan