2013-04-21 17 views
8

Tôi có những gì tôi nghĩ sẽ là một vấn đề đơn giản, nhưng tôi đã không thể tìm thấy câu trả lời thích hợp. Tôi có một mảng đa chiều v[x,y,z] và tôi muốn áp dụng hàm cho mảng dọc theo tham số z bằng biến nhóm (nhóm). Dưới đây là một ví dụ (R):Áp dụng một hàm vào mảng đa chiều với biến nhóm

v<-1:81 
dim(v)<-c(3,3,9) 
group<-c('a','a','a','b','b','b','c','c','c') 

Cho rằng các biến nhóm có 3 cấp (một, bc), kết quả (ra) Tôi đang tìm là một mảng có kích thước 3x3x3. Tôi có thể lấy ra bằng cách sử dụng mã sau đây cho ví dụ trên:

out1<-apply(v[,,c(1:3)],c(1,2),sum) 
out2<-apply(v[,,c(4:6)],c(1,2),sum) 
out3<-apply(v[,,c(7:9)],c(1,2),sum) 

library(abind) 
out<-abind(out1, out2, out3, along=3) 

Câu hỏi của tôi là nếu có một phương tiện nói chung có được kết quả trên, có thể được áp dụng cho mảng chiều lớn và vectơ nhóm dài.

+1

Đưa ra nhận xét của bạn bên dưới câu trả lời của @krlmlr sẽ tốt hơn nếu bạn mô tả chính xác hơn dữ liệu bạn đang làm việc. Thật khó chịu khi phát triển một câu trả lời để được cho biết rằng dữ liệu bạn có là rất khác với những gì bạn mô tả * sẽ không hoạt động *! –

+2

Vì bạn đang xử lý dữ liệu viễn thám, nên bạn có thể xem xét gói 'raster' và các hàm' stack' và 'calc' được tối ưu hóa cho loại dữ liệu này. –

Trả lời

2

Đây là dễ dàng hơn nhiều nếu dữ liệu của bạn được định dạng như khung dữ liệu:

library(plyr) 
vd <- adply(v, 1:3) 
head(vd) 

    X1 X2 X3 V1 
1 1 1 1 1 
2 2 1 1 2 
3 3 1 1 3 
4 1 2 1 4 
5 2 2 1 5 
6 3 2 1 6 

Sau đó, bạn chỉ có thể đính kèm nhóm của bạn ...

vd$group <- rep(group, rep(3 * 3, length(group))) 

... và chia theo này nhóm:

daply(vd, .(group), function(df) { ... }) 

Chức năng ẩn danh { ... } sẽ được gọi một lần cho mỗi g roup, với df chứa các phụ dataframe tương ứng với nhóm đó. Ở đây bạn có thể kết hợp lại và tổng hợp dữ liệu vào một ma trận bằng cách sử dụng máy móc tương tự. Hàm sẽ trả về một mảng các kích thước 3x3x1, chúng sẽ được nối với nhau bằng daply để tạo thành kết quả mong muốn.

+0

Cảm ơn Krlmlr vì đã dành thời gian của bạn. Thật không may, điều đó không giải quyết được vấn đề của tôi. Ví dụ tôi đưa ra là sử dụng một 'mô hình' nhỏ.Các mảng tôi làm việc với dữ liệu cảm biến từ xa rất lớn, theo đó mỗi ma trận trong mảng có thể biểu diễn một ma trận không gian 1000 x 1000 điểm số ngày (kích thước z), bao gồm nhiều năm. Tôi cần tìm giá trị trung bình của mỗi điểm trong ma trận không gian 1000 x 1000 điểm cho mỗi tháng. Trong các phân tích tiếp theo, tôi cũng cần phải duy trì cấu trúc mảng dữ liệu của mình. Cảm ơn một lần nữa cho thời gian của bạn. – Arhopala

6

dễ dàng:

out <- apply(v, c(1, 2), by, group, sum) 

Nhưng để có được các dữ liệu chính xác thứ tự như bạn muốn:

out <- aperm(apply(v, c(1, 2), by, group, sum), c(2, 3, 1)) 
+0

'by' có nghĩa là gì? – krlmlr

+0

Nó là một hàm, tìm kiếm nó lên '? By'. – flodel

+0

Cảm ơn rất nhiều Flodel, tôi thực sự đánh giá cao sự giúp đỡ của bạn. – Arhopala

5

Sử dụng raster gói có thể thích hợp hơn cho nhu cầu của bạn. Nó có một số mã được tối ưu hóa để xử lý dữ liệu cảm biến từ xa, chăm sóc xử lý theo khối. Hãy xem xét ví dụ sau:

## Make 12 rasters, maybe one for each month of the year 
for(i in seq(12)){ 
    assign(paste0("r" , i) , raster(matrix(runif(1e3) , nrow = 1e2))) 
} 

## Create a raster stack from these 
rS <- stack(mget(paste0("r",1:12) , envir = .GlobalEnv)) 

## Use calc to get mean, using by to group by a variable 
## In this example I use the vector (1,1,1,2,2,2,3,3,3,4,4,4) 
## meaning I get means for the first 3 rasters, then the next 3 etc 
## So I get a mean for each quarter 
rMean <- calc(rS , fun = function(x){ by(x , c(rep(1:4 , each=3)) , mean) } ) 

nào trả về một viên gạch raster với 4 lớp (một nghĩa cho mỗi quý):

class  : RasterBrick 
dimensions : 100, 10, 1000, 4 (nrow, ncol, ncell, nlayers) 
resolution : 0.1, 0.01 (x, y) 
extent  : 0, 1, 0, 1 (xmin, xmax, ymin, ymax) 
coord. ref. : NA 
data source : in memory 
names  :   X1,   X2,   X3,   X4 
min values : 0.02096586, 0.04015260, 0.04704145, 0.05884161 
max values : 0.9727491, 0.9303025, 0.9804486, 0.9934670 

Tôi hy vọng bạn có thể thích ứng này để dữ liệu của bạn.

+0

Cảm ơn Simon rất nhiều, có vẻ thú vị để sử dụng với dữ liệu raster. Tôi sẽ thử nghiệm nó với một vài bộ dữ liệu tôi có! – Arhopala

+0

@Arhopala thử nghiệm này như thế nào? Giải pháp này có phù hợp với bạn không? Hay bạn cần nó hiệu quả hơn/nhanh hơn? –

+0

Xin chào Simon, xin lỗi vì đã hơi chậm trả lời, nhưng bận rộn gửi một bản thảo. Tôi đã có thời gian để thử đề xuất của bạn và nó hoạt động tốt. Đó là một chút chậm hơn so với đề nghị của Flodel tuy nhiên. Tôi chạy một system.time trên cả hai và thời gian sử dụng cho Flodel là 14.476 và cho bạn 19.086 trên 269 100x100 ma trận. Hiện tại tôi đang chuyển đổi hình ảnh vệ tinh sang HDF5 hoặc NetCDF, sau đó nhập vào R để phân tích thêm. Cảm ơn bạn đã giúp đỡ. – Arhopala

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