2011-11-23 27 views
6

Tôi có khung và vectơ dữ liệu sau.Làm cách nào để áp dụng hàm đa tham số trong R?

> y 
    v1 v2 v3 
1 1 6 43 
2 4 7 5 
3 0 2 32 

> v 
[1] 1 2 3 

Tôi muốn áp dụng các chức năng sau đây để mỗi ROW ở chỗ khung dữ liệu đó mà v được thêm vào mỗi ROW của y:

x <- function(vector1,vector2) { 
    x <- vector1 + vector2 
} 

... để có được các kết quả này:

v1 v2 v3 
1 2 8 46 
2 5 9 8 
3 1 4 35 

mapply áp dụng các chức năng để COLUMNS:

> z <- mapply(x, y, MoreArgs=list(vector2=v)) 
> z 
    v1 v2 v3 
[1,] 2 7 44 
[2,] 6 9 7 
[3,] 3 5 35 

Tôi đã thử transposing khung dữ liệu để các chức năng sẽ được áp dụng cho các hàng và cột không, nhưng mapply mang lại cho tôi kết quả kỳ lạ sau khi transposing:

> transposed <- t(y) 
> transposed 
    [,1] [,2] [,3] 
v1 1 4 0 
v2 6 7 2 
v3 43 5 32 

> z <- mapply(x, transposed, MoreArgs=list(vector2=v)) 
> z 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 2 7 44 5 8 6 1 3 33 
[2,] 3 8 45 6 9 7 2 4 34 
[3,] 4 9 46 7 10 8 3 5 35 

... Help?

############################ EDIT ################# ########

Cảm ơn tất cả các câu trả lời! Tôi đang học rất nhiều hàm R mới mà tôi chưa bao giờ thấy trước đây, điều này thật tuyệt vời.

Tôi muốn làm rõ câu hỏi trước đây của mình một chút. Điều tôi thực sự hỏi là một câu hỏi tổng quát hơn - cách áp dụng một hàm đa tham số cho mỗi hàng trong R (tại thời điểm này, tôi bị cám dỗ để kết luận rằng tôi chỉ nên sử dụng một vòng lặp, nhưng tôi muốn tìm ra nếu nó là có thể, chỉ để tham khảo trong tương lai ...) (Tôi cũng cố ý kiềm chế hiển thị mã tôi đang làm việc với vì nó là loại lộn xộn).

tôi đã cố gắng sử dụng chức năng quét như đã được đề nghị, nhưng tôi nhận được lỗi sau:

testsweep <- function(vector, z, n) { 
    testsweep <- z 
} 
> n <- names(Na_exp) 
> n 
[1] "NaCl.10000.2hr.AVG_Signal" "NaCl.10000.4hr.AVG_Signal" 


> t <- head(Li_fcs,n=1) 
> t 
    LiCl.1000.1hr.FoldChange LiCl.2000.1hr.FoldChange LiCl.5000.1hr.FoldChange 
[1,]    -0.05371838    -0.1010928    -0.01939986 
    LiCl.10000.1hr.FoldChange LiCl.1000.2hr.FoldChange 
[1,]     0.1275617    -0.107154 
    LiCl.2000.2hr.FoldChange LiCl.5000.2hr.FoldChange 
[1,]    -0.06760782    -0.09770226 
    LiCl.10000.2hr.FoldChange LiCl.1000.4hr.FoldChange 
[1,]    -0.1124188    -0.06140386 
    LiCl.2000.4hr.FoldChange LiCl.5000.4hr.FoldChange 
[1,]    -0.04323497    -0.04275953 
    LiCl.10000.4hr.FoldChange LiCl.1000.8hr.FoldChange 
[1,]    0.03633496    0.01879461 
    LiCl.2000.8hr.FoldChange LiCl.5000.8hr.FoldChange 
[1,]     0.257977    -0.06357423 
    LiCl.10000.8hr.FoldChange 
[1,]    0.07214176 


> z <- colnames(Li_fcs) 
> z 
[1] "LiCl.1000.1hr.FoldChange" "LiCl.2000.1hr.FoldChange" 
[3] "LiCl.5000.1hr.FoldChange" "LiCl.10000.1hr.FoldChange" 
[5] "LiCl.1000.2hr.FoldChange" "LiCl.2000.2hr.FoldChange" 
[7] "LiCl.5000.2hr.FoldChange" "LiCl.10000.2hr.FoldChange" 
[9] "LiCl.1000.4hr.FoldChange" "LiCl.2000.4hr.FoldChange" 
[11] "LiCl.5000.4hr.FoldChange" "LiCl.10000.4hr.FoldChange" 
[13] "LiCl.1000.8hr.FoldChange" "LiCl.2000.8hr.FoldChange" 
[15] "LiCl.5000.8hr.FoldChange" "LiCl.10000.8hr.FoldChange" 

Nhưng khi tôi cố gắng áp dụng quét ...

> test <- sweep(t, 2, z, n, FUN="testsweep") 
Error in if (check.margin) { : argument is not interpretable as logical 
In addition: Warning message: 
In if (check.margin) { : 
    the condition has length > 1 and only the first element will be used 

Khi tôi loại bỏ các n tham số từ ví dụ kiểm tra này, quét hoạt động tốt. Điều này gợi ý cho tôi rằng việc quét không thể được sử dụng trừ khi tất cả các tham số được cung cấp để quét hoặc là cùng một số cột như vector t, hoặc độ dài 1. Vui lòng sửa tôi nếu tôi bị nhầm lẫn ...

Trả lời

0

Cách sử dụng ứng dụng?

t(apply(y, 1, function(x) x + v)) 
    [,1] [,2] [,3] 
[1,] 2 8 46 
[2,] 5 9 8 
[3,] 1 4 35 

Tôi không biết tại sao áp dụng trả về hàng như columms để nó cần được chuyển đổi.

+0

Tôi chắc chắn sẽ xem xét mdply tạo thành gói plyr. Điều này chính xác làm những gì bạn yêu cầu. –

+0

Tôi chắc chắn sẽ xem mdply mẫu gói plyr. Điều này chính xác làm những gì bạn yêu cầu. –

3

Bạn đang yêu cầu để "quét" v trên các hàng của y với dấu "+" chức năng:

sweep(y, 1, v, FUN="+") 
    v1 v2 v3 
1 2 7 44 
2 6 9 7 
3 3 5 35 
+0

Tôi nghĩ 'MARGIN' cần phải là 2 vì bạn muốn áp dụng' v' vào các cột 'y'. –

+0

Vâng. Tôi cũng nghĩ thế, nhưng chúng tôi đều sai. –

+0

Tôi nghĩ quét là chính xác những gì tôi đang tìm kiếm. Vấn đề thực sự phức tạp hơn là chỉ thêm vectơ - tôi chỉ sử dụng nó như một ví dụ vì nó là thứ đơn giản nhất mà bạn nghĩ đến. Những gì tôi đã thực sự tìm kiếm là một cách để dễ dàng và nhanh chóng áp dụng một chức năng đa tham số cho mỗi hàng - và điều đó dường như là những gì quét không. Cảm ơn! –

2

Tôi không nghĩ rằng bạn cần mapply đây.Chỉ cần sử dụng t() trực tiếp hoặc bạn có thể sử dụng rep() để làm cho trận đấu tái chế như bạn muốn:

> set.seed(1) 
> mat <- matrix(sample(1:100, 9, TRUE), ncol = 3) 
> vec <- 1:3 
> 
> mat 
    [,1] [,2] [,3] 
[1,] 27 91 95 
[2,] 38 21 67 
[3,] 58 90 63 
#Approach 1 using t() 
> ans1 <- t(t(mat) + vec) 
#Approach 2 using rep() 
> ans2 <- mat + rep(vec, each = nrow(mat)) 
#Are they the same? 
> identical(ans1, ans2) 
[1] TRUE 
#Hurray! 
> ans1 
    [,1] [,2] [,3] 
[1,] 28 93 98 
[2,] 39 23 70 
[3,] 59 92 66 
+0

+1 để tái chế thủ công qua 'rep' bằng' each = '. –

2

Nếu vấn đề thực tế của bạn thực sự là không có phức tạp hơn này, bạn có thể tận dụng các quy tắc tái chế R. Trước tiên, bạn cần chuyển đổi y, sau đó thêm, sau đó chuyển đổi kết quả vì ma trận R được lưu trữ trong column-major order.

t(t(y)+v) 
    v1 v2 v3 
1 2 8 46 
2 5 9 8 
3 1 4 35 
0

Tôi chắc chắn sẽ xem xét mdply tạo thành gói plyr. Điều này chính xác những gì bạn muốn làm:

mdply(data.frame(mean = 1:5, sd = 1:5), rnorm, n = 2) 
Các vấn đề liên quan