2011-01-21 37 views
11

Tôi có một danh sách các hàmÁp dụng danh sách hàm n cho mỗi hàng của một khung dữ liệu?

funs <- list(fn1 = function(x) x^2, 
      fn2 = function(x) x^3,    
      fn3 = function(x) sin(x), 
      fn4 = function(x) x+1) 
#in reality these are all f = splinefun() 

Và tôi có một dataframe:

mydata <- data.frame(x1 = c(1, 2, 3, 2), 
        x2 = c(3, 2, 1, 0), 
        x3 = c(1, 2, 2, 3), 
        x4 = c(1, 2, 1, 2)) 
#actually a 500x15 dataframe of 500 samples from 15 parameters 

Đối với mỗi i hàng, tôi muốn đánh giá chức năng j trên mỗi j cột và tổng kết quả:

unlist(funs) 
attach(mydata) 
a <- rep(NA,4) 
for (i in 1:4) { 
    a[i] <- sum(fn1(x1[i]), fn2(x2[i]), fn3(x3[i]), fn4(x4[i])) 
} 

Làm cách nào để tôi thực hiện điều này một cách hiệu quả? Đây có phải là dịp thích hợp để thực hiện các chức năng plyr không? Nếu vậy, làm thế nào?

câu hỏi thưởng: tại sao là a[4]NA?

Đây có phải là thời điểm thích hợp để sử dụng các chức năng từ plyr, nếu có, làm cách nào tôi có thể làm như vậy?

+1

@abe cho đoạn mã thứ ba, bạn cần phải là 'không công khai (vui)' và 'đính kèm (mydata)' hoặc sử dụng 'funs $ fn1' và' mydata $ x1' –

+0

@David cảm ơn vì đã sửa, tôi đã thay đổi mã để phản ánh điều này - nhưng điều này chính xác là sự lộn xộn mà tôi muốn tránh. – Abe

+2

Vâng, đối với điểm thưởng, câu trả lời là không có phần tử thứ 4 trong mydata $ x4 hoặc bất kỳ cột nào trong khung dữ liệu đó. Một bình luận thêm .. chỉ cần gõ unlist (funs) không có gì trừ khi bạn gán kết quả cho một cái gì đó. Chào mừng bạn đến với chương trình chức năng. –

Trả lời

9

Bỏ qua đoạn mã của bạn và gắn bó với đặc điểm kỹ thuật ban đầu của bạn mà bạn muốn áp dụng chức năng j vào số cột j và sau đó "tổng hợp các kết quả" ... bạn có thể làm:

mapply(do.call, funs, lapply(mydata, list)) 
#  [,1] [,2]  [,3] [,4] 
# [1,] 1 27 0.8414710 2 
# [2,] 4 8 0.9092974 3 
# [3,] 9 1 0.9092974 3 

Tôi không chắc chắn cách bạn muốn bây giờ thêm kết quả (tức là hàng khôn ngoan hoặc cột khôn ngoan), vì vậy bạn có thể làm rowSums hoặc colSums trên ma trận này. Ví dụ:

colSums(mapply(do.call, funs, lapply(mydata, list))) 
# [1] 14.000000 36.000000 2.660066 8.000000 
+0

cảm ơn sự giúp đỡ này; Tôi sẽ sử dụng rowSums nhưng đây là khái niệm mà tôi đang tìm kiếm. – Abe

+0

Tôi không hiểu danh sách cuối cùng làm gì, không phải là đối số thứ hai để làm.call một danh sách các đối số cho hàm? – Abe

+0

Tôi đã chỉnh sửa biểu thức thứ hai ở trên một chút (bạn không cần phải thực hiện 'as.list'). Bạn cần phải thực hiện 'lapply (mydata, list)' để biến 'mydata' thành danh sách các danh sách. Sau đó 'mapply' làm' do.call' lấy từng hàm trong 'funs' và lấy danh sách thành viên tương ứng của' lapply (mydata, list) ', chính nó là một danh sách. –

4

Tại sao không chỉ viết một hàm cho tất cả 4 và áp dụng nó cho khung dữ liệu? Tất cả các chức năng của bạn đang vector hóa, và như vậy là splinefun, và điều này sẽ làm việc:

fun <- function(df) 
    cbind(df[, 1]^2, df[, 2]^3, sin(df[, 3]), df[, 4] + 1) 

rowSums(fun(mydata)) 

Đây là đáng kể hiệu quả hơn "Foring" hay "áp dụng" trên các hàng.

0

tôi đã cố gắng sử dụng plyr::each:

library(plyr) 
sapply(mydata, each(min, max)) 
    x1 x2 x3 x4 
min 1 0 1 1 
max 3 3 3 2 

và nó hoạt động tốt, nhưng khi tôi vượt qua chức năng tùy chỉnh tôi nhận được:

sapply(mydata, each(fn1, fn2)) 
Error in proto[[i]] <- fs[[i]](x, ...) : 
    more elements supplied than there are to replace 

each có tài liệu rất ngắn, tôi không hoàn toàn nhận được những gì vấn đề.

Các vấn đề liên quan