2012-12-10 44 views
8

Hãy tưởng tượng bạn có một mảng 3 chiều với hàng, cột, và các lớp:Áp dụng một chức năng để mỗi lớp của một mảng 3d, trả lại một mảng

A <- array (1:27, c(3,3,3)) 

và tưởng tượng bạn có một chức năng mà phải mất một ma trận làm đầu vào và trả về ma trận làm đầu ra, như t.

Làm cách nào bạn có thể áp dụng hàm cho từng lớp của mảng, trả lại một mảng có cùng kích thước với mảng đầu tiên?

Tôi cảm thấy mình có thể làm điều đó với apply bằng cách nào đó, nhưng tôi không thể.

Câu hỏi thưởng (Tôi rất biết ơn nếu bạn trả lời câu hỏi này): có nhanh hơn để thực hiện việc này hay tạo danh sách mỗi ma trận lớp và lapply chức năng cho chúng?

-

Chỉnh sửa: xin đừng nghĩ rằng câu hỏi này được trả lời - câu trả lời dưới đây không trả lời câu hỏi.

Trả lời

4

Bạn phải suy nghĩ về (các) lề mà bạn muốn trích xuất các giá trị.

hoán chuyển vị trí mỗi người trong số các ma trận chiều 3rd bằng cách áp dụng trên kích thước 1 và 2 (hàng và cột cho muốn của một từ tốt hơn)

apply(A,1:2,t) 
, , 1 

    [,1] [,2] [,3] 
[1,] 1 2 3 
[2,] 10 11 12 
[3,] 19 20 21 

, , 2 

    [,1] [,2] [,3] 
[1,] 4 5 6 
[2,] 13 14 15 
[3,] 22 23 24 

, , 3 

    [,1] [,2] [,3] 
[1,] 7 8 9 
[2,] 16 17 18 
[3,] 25 26 27 

Bạn cũng có thể sử dụng plyraaply mà có thể hoạt động bằng trực giác hơn

library(plyr) 

aaply(A,3,t) 
, , = 1 


X1 1 2 3 
    1 1 4 7 
    2 10 13 16 
    3 19 22 25 

, , = 2 


X1 1 2 3 
    1 2 5 8 
    2 11 14 17 
    3 20 23 26 

, , = 3 


X1 1 2 3 
    1 3 6 9 
    2 12 15 18 
    3 21 24 27 

Khi mà là nhanh hơn lapply hoặc apply, tôi sẽ nghĩ có lẽ lapply sẽ giành chiến thắng, nhưng bạn vẫn sẽ phải làm suy nghĩ về lợi nhuận mà bạn muốn trích xuất các ma trận từ đó.

Tôi thường tìm thấy nó dễ dàng hơn để suy nghĩ trong một chiều. Mọi thứ sẽ tiến thẳng hơn nếu trái đất phẳng!

+0

Đó không phải là ý tôi. Câu trả lời đúng phải có lớp đầu tiên giống như 't (ma trận (1: 9, 3, 3))', không phải là của cả hai. –

+0

Đó là ý của tôi về việc phải suy nghĩ cẩn thận về các thứ nguyên để có được những gì bạn muốn. – mnel

+0

Không có sự kết hợp có thể có của lợi nhuận cho câu trả lời tôi đang tìm kiếm, mặc dù. –

1

Khả năng khác cho chuyển vị là hàm aperm.

A <- array (1:27, c(3,3,3)) 
# aperm permute the dimensions in the given order 
# here we want to permute dimension 1 and 2 
# so the new order is 2-1-3 instead of 1-2-3 
aperm(A, c(2,1,3)) 
    , , 1 

    [,1] [,2] [,3] 
[1,] 1 2 3 
[2,] 4 5 6 
[3,] 7 8 9 

, , 2 

    [,1] [,2] [,3] 
[1,] 10 11 12 
[2,] 13 14 15 
[3,] 16 17 18 

, , 3 

    [,1] [,2] [,3] 
[1,] 19 20 21 
[2,] 22 23 24 
[3,] 25 26 27 

Theo như áp dụng một chức năng cho mỗi lớp (nói rằng bạn muốn nhân từng lớp bằng một giá trị khác) là có liên quan, đây là một khả năng:

vec <- c(1,5,3) 
lapply(seq_along(vec), function(x)A[,,x]*vec[x]) 
[[1]] 
    [,1] [,2] [,3] 
[1,] 1 4 7 
[2,] 2 5 8 
[3,] 3 6 9 

[[2]] 
    [,1] [,2] [,3] 
[1,] 50 65 80 
[2,] 55 70 85 
[3,] 60 75 90 

[[3]] 
    [,1] [,2] [,3] 
[1,] 57 66 75 
[2,] 60 69 78 
[3,] 63 72 81 

Nhưng như bạn thấy nó tạo ra một danh sách, vì vậy nó cần thêm một bước bằng chức năng simplify2array:

simplify2array(lapply(seq_along(vec),function(x)A[,,x]*vec[x])) 
, , 1 

    [,1] [,2] [,3] 
[1,] 1 4 7 
[2,] 2 5 8 
[3,] 3 6 9 

, , 2 

    [,1] [,2] [,3] 
[1,] 50 65 80 
[2,] 55 70 85 
[3,] 60 75 90 

, , 3 

    [,1] [,2] [,3] 
[1,] 57 66 75 
[2,] 60 69 78 
[3,] 63 72 81 

Hoặc trực tiếp với sapply:

sapply(seq_along(vec), function(x)A[,,x]*vec[x], simplify="array") 
, , 1 

    [,1] [,2] [,3] 
[1,] 1 4 7 
[2,] 2 5 8 
[3,] 3 6 9 

, , 2 

    [,1] [,2] [,3] 
[1,] 50 65 80 
[2,] 55 70 85 
[3,] 60 75 90 

, , 3 

    [,1] [,2] [,3] 
[1,] 57 66 75 
[2,] 60 69 78 
[3,] 63 72 81 
+1

Thật tuyệt. Tôi đã sử dụng 't' tùy ý - tôi có một quá trình ngẫu nhiên phức tạp mà tôi muốn áp dụng cho ma trận - nhưng thật tuyệt khi biết' aperm' tồn tại. :-) Các giải pháp khác cũng tốt đẹp, nhưng tôi đã hy vọng làm điều đó một cách chức năng tức là truyền dữ liệu vào hàm áp dụng thay vì có hàm hoạt động trên dữ liệu ngoài phạm vi cục bộ của nó. –

+0

Bạn có nghĩa là một cái gì đó như 'sapply (seq_along (vec), chức năng (x, X) {X [,, x] * vec [x]}, đơn giản hóa =" mảng ", X = A)'? – plannapus

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