2014-11-22 69 views
2

的多範圍比方說,我有行刪除R中

v <- matrix(seq(150), 50, 3) 
k <- c(10, 40) 
delta <- 5 

我怎麼能同時刪除10三角洲10個+三角行和40-Δ40個+增量行?

我用vnew <- v[-((k-delta):(k+delta)),],但似乎該命令只使用k(它是10)的第一個元素刪除並且不會刪除40-delta到40 + delta行。有沒有人有任何想法如何做到這一點?

哦,我將需要把它放在一個循環中,每次迭代中更新k,所以v[c(-{(10-delta):(10+delta)},-{(40-delta):(40+delta)}),]將不起作用。

+1

'-c(sapply(SEQ(K),函數(I)(K [I] -delta):(k [i] + delta)))' – 2014-11-22 21:47:58

+0

在k中總是有2個元素? – 2014-11-22 21:49:37

+0

在每次迭代中'delta'是否改變?如果不是的話,你可以使用類似於:'d < - -delta:delta;對於(...){... vnew < - v [ - (rep(k,each = length(d))+ d)] ...}' – sgibb 2014-11-22 21:52:00

回答

1

理查德·斯克裏文的回答只返回索引10-delta:10+delta和線40-delta:40+delta到從V中刪除要effectly做到這一點,你必須用你嘗試過這樣的東西結合它:

v[-c(sapply(seq(k), function(i) (k[i]-delta):(k[i]+delta))), ]

或更短但骯髒(?):v[-sapply(seq(k), function(i) (k[i]-delta):(k[i]+delta)), ]

+0

是的,這工作。謝謝! – djoeraganberas 2014-11-22 22:00:44

1

如果k在每次迭代增長和delta不會改變我建議如下:

d <- -delta:delta 

for (...) { 
# ... 
vnew <- v[-(rep(k, each=length(d)) + d),] 
# ... 
} 

對於示例:

d <- -5:5 
k <- c(10, 40) 
rep(k, each=length(d)) + d 
# [1] 5 6 7 8 9 10 11 12 13 14 15 35 36 37 38 39 40 41 42 43 44 45 

編輯:這兩種解決方案的一個基準:

library("rbenchmark") 

idx1 <- function(k, delta) { 
    d <- -delta:delta 

    lapply(seq_along(k), function(i) { 
    rep(k[1:i], each=length(d)) + d 
    }) 
} 

idx2 <- function(k, delta) { 
    lapply(seq_along(k), function(i) { 
    c(sapply(1:i, function(ii) { 
     (k[ii]-delta):(k[ii]+delta) 
    })) 
    }) 
} 

set.seed(1) 
k <- sample(1e3, 1e2) 
delta <- 5 

all.equal(idx1(k, delta), idx2(k, delta)) 
# [1] TRUE 

benchmark(idx1(k, delta), idx2(k, delta), order="relative", replications=100) 
#    test replications elapsed relative user.self sys.self user.child sys.child 
# 1 idx1(k, delta)   100 0.174 1.000  0.172  0   0   0 
# 2 idx2(k, delta)   100 1.579 9.075  1.576  0   0   0