2015-05-15 17 views
7

Tôi đang cố tránh sử dụng vòng lặp bằng cách sử dụng apply để áp dụng hàm do người dùng xác định cho ma trận. Vấn đề tôi có là có các tham số bổ sung mà hàm của tôi sử dụng và chúng khác nhau đối với mỗi cột của ma trận. Dưới đây là một ví dụ đồ chơi.Sử dụng "áp dụng" để áp dụng hàm vào ma trận trong đó các thông số là cột cụ thể

Nói rằng tôi có các chức năng sau:

foo <- function(x, a, b, c) return((a*x + b)^c) 

và tôi muốn áp dụng nó vào một ma trận bar sử dụng giá trị khác nhau của a, bc cho mỗi cột.

bar <- matrix(1:15, ncol = 3) 
a <- 4:6 
b <- 3:1 
c <- 1:3 

Trong trường hợp này, đối với cột đầu tiên của bar, sau đó a=4, b=3, và c=1. Tôi cố gắng này,

apply(bar, 2, foo, a=a, b=b, c=c) 

nhưng điều này rõ ràng là không đúng, vì mỗi cột sử dụng tất cả các thông số liên tục trước khi gói lại các tham số đầu tiên một lần nữa. Bất kỳ đề xuất?

Trả lời

12

Chúng ta có thể split các 'bar' bằng 'cột' (col(bar)) và với mapply chúng ta có thể áp dụng 'foo' cho 'a' tương ứng, 'b', 'c' giá trị cho mỗi cột của 'bar'

mapply(foo, split(bar, col(bar)), a, b, c) 

Hoặc mà không sử dụng apply

ind <- col(bar) 
(a[ind]*bar +b[ind])^c[ind] 
+2

Thay vì 'chia', bạn cũng có thể sử dụng' as.data.frame'. – nicola

+0

@nicola Có, tôi nghĩ rằng để giữ nó trong 'ma trận ' – akrun

+2

Tôi đã upvoted đầu tiên và bây giờ muốn có khả năng để thêm phiếu cho chỉnh sửa đặc biệt thanh lịch. –

2

bạn có thể đặt thông số của bạn vào vector:

newbar <- rbind(a,b,c,bar) 
newfoo <- function(z){x <- z[-(1:3)]; (z[1]*x+z[2])^z[3]} 
apply(newbar,2,newfoo) 

mang đến cho

[,1] [,2] [,3] 
    7 1024 300763 
    11 1369 389017 
    15 1764 493039 
    19 2209 614125 
    23 2704 753571 
2

Bạn có thể sử dụng sweep; thường này là dành cho trừ đi giá trị trung bình từ mỗi cột, nhưng bạn có thể vượt qua trong một chỉ số thay thế để nhận indexing song song trên a, b và c:

> sweep(bar, 2, seq_along(a), function(x,i) foo(x, a[i], b[i], c[i]), FALSE) 
    [,1] [,2] [,3] 
[1,] 7 1024 300763 
[2,] 11 1369 389017 
[3,] 15 1764 493039 
[4,] 19 2209 614125 
[5,] 23 2704 753571 
+0

Xem thêm http://stackoverflow.com/questions/3444889/how-to-use-the-r-function-sweep –

9

Tôi không thấy lý do tại sao bạn bận tâm với một chức năng ở tất cả các :

> a <- matrix(4:6,nrow = 5,ncol = 3,byrow = TRUE) 
> b <- matrix(3:1,nrow = 5,ncol = 3,byrow = TRUE) 
> c <- matrix(1:3,nrow = 5,ncol = 3,byrow = TRUE) 
> (a*bar + b)^c 
    [,1] [,2] [,3] 
[1,] 7 1024 300763 
[2,] 11 1369 389017 
[3,] 15 1764 493039 
[4,] 19 2209 614125 
[5,] 23 2704 753571 
+0

Đó là thanh lịch hơn, mặc dù tôi đã thử nghiệm nó .. – akrun

+0

@akrun Ah, tôi đã bỏ lỡ kết thúc câu trả lời của bạn. – joran

+0

Không sao đâu. Tôi sẽ không đoán nó anyway – akrun

3

tôi đoán rằng bạn chỉ có thể transpose ma trận và sử dụng vector hóa:

t(foo(t(bar),a,b,c)) 

này nên làm việc cho mỗi vector hóa foo.

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