2011-11-06 30 views
5

Cho phép nói rằng tôi có một mảng, foo, trong R có kích thước == c(150, 40, 30). Bây giờ, nếu tôi:Đảo ngược áp dụng với rbind

bar <- apply(foo, 3, rbind) 

dim(bar) tại là c(6000, 30).

Cách thanh lịch và chung chung nhất để đảo ngược quy trình này là gì và đi từ bar đến foo sao cho chúng giống hệt nhau?

Sự cố không nhận được kích thước phù hợp, nhưng thu thập dữ liệu theo cùng thứ tự, trong phạm vi, thứ nguyên gốc, được tôn trọng.

Cảm ơn bạn đã dành thời gian, tôi mong nhận được phản hồi của bạn.

P.S. Đối với những người nghĩ rằng đây là một phần của một vấn đề lớn hơn, nó là, và không, tôi không thể sử dụng plyr, được nêu ra.

+0

Bạn đã xem 'aaply' chưa? Nó thường làm một công việc tốt hơn cho các kích thước bạn mong đợi – hadley

+0

Các cuộc gọi đến 'rbind' không có ý nghĩa - vì bạn chỉ cho nó một đối số, nó sẽ không làm bất cứ điều gì hữu ích. 'danh tính' sẽ làm điều tương tự ... Tôi mở rộng quan sát này trong câu trả lời của tôi dưới đây. – Tommy

Trả lời

7

Tôi nghĩ rằng bạn chỉ có thể gọi array một lần nữa và chỉ định kích thước ban đầu:

m <- array(1:210,dim = c(5,6,7)) 
m1 <- apply(m, 3, rbind) 
m2 <- array(as.vector(m1),dim = c(5,6,7)) 
all.equal(m,m2) 
[1] TRUE 
+0

Hmm, tôi nghĩ rằng tôi đã thử điều này, nhưng phải là một trong những đêm bởi vì điều này hoạt động tốt. Cám ơn sự tử tế của anh! – brews

+3

Tùy thuộc vào thứ tự của dữ liệu, bạn có thể cần phải tạo mảng với các thứ nguyên theo thứ tự sai và sau đó sử dụng 'aperm'. –

4

Tôi đang tự hỏi về chuyển đổi ban đầu của bạn. Bạn gọi rbind từ apply, nhưng điều đó sẽ không làm bất cứ điều gì - bạn cũng có thể gọi là identity!

foo <- array(seq(150*40*30), c(150, 40, 30)) 
bar <- apply(foo, 3, rbind) 
bar2 <- apply(foo, 3, identity) 
identical(bar, bar2) # TRUE 

Vì vậy, bạn thực sự muốn đạt được điều gì? Tôi đã được giả định rằng bạn đã có một vài (40) ma trận lát và muốn ngăn xếp chúng và sau đó unstack chúng một lần nữa. Nếu vậy, mã sẽ được tham gia nhiều hơn @joran đề xuất. Bạn cần một số cuộc gọi đến aperm (như @Patrick Burns gợi ý):

# Make a sample 3 dimensional array (two 4x3 matrix slices): 
m <- array(1:24, 4:2) 

# Stack the matrix slices on top of each other 
m2 <- matrix(aperm(m, c(1,3,2)), ncol=ncol(m)) 

# Reverse the process 
m3 <- aperm(array(m2, c(nrow(m),dim(m)[[3]],ncol(m))), c(1,3,2)) 

identical(m3,m) # TRUE 

Trong mọi trường hợp, aperm thực sự mạnh mẽ (và hơi khó hiểu). Học tập rất đáng giá ...

+0

Điểm tốt, việc chia nhỏ hai thứ nguyên đầu tiên về cơ bản là những gì tôi cần. 'aperm' có vẻ hơi lạ một chút, nhưng tôi sẽ xem xét nó. Nó có thể là phương pháp tốt nhất. Cảm ơn bạn đã đề nghị. – brews