2012-11-28 24 views
5

मुझे ऐसे फ़ंक्शन की आवश्यकता है जो आर में एक बहुआयामी सरणी को सबसेट करता हो; पकड़ यह है कि मुझे नहीं पता कि उस आयाम के साथ कौन सा आयाम या लंबाई कार्य को बुलाया जाता है।सरणी इंडेक्सिंग संरक्षित संरचना

# subset a 3-d array; leave dims 1 and 2, but start 3rd dim at its 11th value 
mydim <- dim(myarr) 
myarr[, , 11:mydim[3]] 

# subset a 4-d array; leave dims 1, 3 and 4, but start 2rd dim at its 8th value 
mydim <- dim(myarr) 
myarr[, 8:mydim[2], , ] 

मैं हमेशा ठीक एक आयाम में सबसेट तक की जरूरत है, और subsetting, कुछ की तुलना में 1. मैं भी सरणी संरचना के संरक्षण की जरूरत अन्य मूल्य पर शुरू करने के लिए हमेशा होता है तो विन्यास में, मैट्रिक्स अनुक्रमण अपील नहीं लगती है। अग्रिम में धन्यवाद।

+0

दिलचस्प। जब आप कहते हैं कि "कितना" आप का मतलब है कि उस आयाम के साथ कितनी लंबाई या कुछ अलग है? –

+0

हां, मेरा मतलब है कि उस आयाम के साथ लंबाई –

+0

मैं इस प्रकार के ऑपरेशन के लिए सूची() का सुझाव देता हूं –

उत्तर

1

यहाँ एक विकल्प है कि एक मैट्रिक्स के आधार पर एक सरणी subsetting की संभावना का लाभ लेता है:

myarr <- array(1:(2*3*4), dim = c(2, 3, 4)) 

myfun <- function(arr, from, len, Dim){ 
    dimArr <- dim(arr) 
    if(missing(len)){ 
     subIdx <- from:dimArr[Dim] 
    } else { 
     subIdx <- from:(from + len - 1) 
    } 
    arrD <- lapply(as.list(dimArr), seq_len) 
    arrD[[Dim]] <- subIdx 
    subMat <- as.matrix(do.call(expand.grid, arrD)) 
    array(arr[subMat], dim = lapply(arrD, length)) 
} 

> myfun(myarr, 2, 1, 3) 
, , 1 

    [,1] [,2] [,3] 
[1,] 7 9 11 
[2,] 8 10 12 

> myfun(myarr, 2, Dim = 3) 
, , 1 

    [,1] [,2] [,3] 
[1,] 7 9 11 
[2,] 8 10 12 

, , 2 

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

, , 3 

    [,1] [,2] [,3] 
[1,] 19 21 23 
[2,] 20 22 24 
+0

@ जैकटैनर, "लंबाई के साथ" टिप्पणी को देखा (और एक अलग तरीके से समझ लिया)। अगर संपादन आप जो चाहते थे वह नहीं करता है, तो कृपया सूचित करें! – BenBarnes

1

यहां हम जाते हैं! भी परीक्षण किया गया ...

sampleArray <- function(myarr, dm, start, leng) { 
    ## arguments: 
    ## dm is the dimension selected 
    ## start is where in dm to being 
    ## leng is how far in from dm to go 
    ## start+leng <= dim(myarr)[dm] 

    leng <- leng-1 

    # error check 
    if (start+leng > dim(myarr)[dm]) 
     warning("leng too long by ", start+leng - dim(myarr)[dm], ".") 

    #initialize a vector of all TRUE 
    indx <- as.list(rep(TRUE, length(dim(myarr)))) 

    # change the required dimension to the required sequence 
    indx[[dm]] <- seq(start, start+leng) 
    indx <- paste(indx, collapse=",") 

    expr <- paste0("myarr[", indx, "]") 

    # return the appropriate sample 
    eval(parse(text=expr)) 
    } 

उदाहरण:

# sample array 
myarr <- array(1:2250, dim=c(15, 10, 15)) 

# example call 
sampleArray(myarr, dm=2, start=4, leng=3) 
+0

काम नहीं करता है: इंडक्स एक वेक्टर है, और इसके तीसरे मान को दूसरे वेक्टर में बदलना विफल रहता है "प्रतिस्थापित करने के लिए आइटम की संख्या प्रतिस्थापन लंबाई के एकाधिक नहीं " –

+0

@ जैक टैनर - बस इसे संपादित किया। यह अब काम करना चाहिए –

+0

यह लगभग काम करता है! आपका मतलब है + लेंग -1 शुरू करें। मैंने दूसरे जवाब को स्वीकार किया क्योंकि यह बग मुक्त था, लेकिन मुझे एक अच्छा विकल्प दिखाने के लिए धन्यवाद। –

संबंधित मुद्दे