2016-01-09 2 views
1

Р: Предположимподсчета R значения вектора в диапазоне заданной двумя другими векторами

length(v)=n length(a)=m=length(b), 
n and m are large; 
v, a, b may contain NA or NaN's; 
a not necessarily smaller than b. 

Как найти количество таких пар индексов Ij, что

a[j] < v[i] < b[j] 

Как найти номер такой (I, J), что либо

a[j] < v[i] < b[j] or a[j] > v[i] > b[j] 

Это кажется слишком медленным:

sumrange <- function(v,ma) 
{ 
    s <- 0 
    for(i in 1:length(v)) 
    { 
    s <- s + sum(v[i] > ma[,1] & ma[,2] > v[i], na.rm = TRUE) 
    } 
    s 
} 
result <- sumrange(v, cbind(a, b)) 

РЕДАКТИРОВАТЬ: @DatamineR

a<-c(1,6,4,2,NA) 
b<-c(5,4,0,7,0) 
v<-c(3,5) 

возможных пар в вопросе 1:

1<3<5 (1,1) 
2<3<7 (1,4) 
2<5<7 (2,4) 

результат = 3

возможных пар в вопросе 2: все выше и

6> 5> 4 (2,2)

результат = 3 + 1 = 4

EDIT: На самом деле он работает лучше один первый капель НС-х

vc<-na.omit(v) 
ma<-na.omit(cbind(a,b)) 
result<-sumrange(vc,ma) 
+0

Если вы предоставили простой пример и набор данных, было бы гораздо проще, чтобы помочь вам – DatamineR

+0

также , ожидаемый результат помог бы, так как это помогло бы убедиться, что цикл, который у вас есть, - это то, что вы намеревались. В цикле у вас есть, вы сравниваете 1 элемент 'v' с одним целым столбцом' m', это то, что вы намеревались сделать? – steveb

ответ

0

Может быть, как это?

# some data: 
set.seed(123) 
a <- sample(1:15, 10) 
b <- sample(1:15, 11) 
c <- sample(1:15, 10) 
a;b;c 
[1] 5 12 6 11 14 1 15 8 4 3 
[1] 15 7 9 14 2 13 3 1 10 6 5 
[1] 11 9 13 8 12 6 10 3 2 14 


res <- sapply(b, function(x) apply(cbind(a,c), 1, function(y) (y[1] < x) & (x < y[2]))) 
which(res, arr.ind = TRUE) 
     row col 
[1,] 1 2 
[2,] 3 2 
[3,] 10 2 
[4,] 1 3 
[5,] 3 3 
[6,] 10 3 
[7,] 6 5 
[8,] 10 6 
[9,] 6 7 
[10,] 1 9 
[11,] 3 9 
[12,] 10 9 
[13,] 1 10 
[14,] 10 10 
[15,] 6 11 
[16,] 10 11 

Здесь первый столбец является j, а второй столбец является i.

Чтобы включить оба условия:

res2 <- sapply(b, function(x) apply(cbind(a,c), 1, function(y) ((y[1] < x) & (x < y[2])) | ((y[1] > x) & (x > y[2])))) 
which(res2, arr.ind = TRUE) 
     row col 
[1,] 1 2 
[2,] 3 2 
[3,] 8 2 
[4,] 10 2 
[5,] 1 3 
[6,] 3 3 
[7,] 4 3 
[8,] 10 3 
[9,] 7 4 
[10,] 6 5 
[11,] 5 6 
[12,] 7 6 
[13,] 10 6 
[14,] 6 7 
[15,] 9 7 
[16,] 1 9 
[17,] 2 9 
[18,] 3 9 
[19,] 4 9 
[20,] 10 9 
[21,] 1 10 
[22,] 8 10 
[23,] 10 10 
[24,] 6 11 
[25,] 8 11 
[26,] 10 11 
+0

Спасибо, я запустил ваш код, и он отлично справляется и дает всю информацию, но слишком много, так как я хотел только количество пар (теперь, возможно, я также захочу иметь пары тоже 8) Сопротивление/применение комбо работает все же медленнее, чем мой примитив для цикла. На небольшом образце с m = 1000 и n = 2000 и с датами даты: цикл for работает на 0.28 (с использованием proc.time()) и комбо для 36.08. Я все еще ищу ускорение. – Kraxxus

0

Я нашел немного более быстрый способ, с помощью гальки Это работает лучше всего, если один удаляет заранее Акрополя

require(lattice) 
vc<-na.omit(v) 
ma<-na.omit(cbind(a,b)) 
sh<-shingle(vc,ma) 
res<-sapply(levels(sh), function(x) sum(x[1] < vc & vc <= x[2])) 
result<-sum(res) 

Длительность задержки т = 1000 (сводится к 912 by na.omit) и n = 2000 составляет 0,12 по сравнению с 0,28 с петлей для обработки (функция суммирования) и 0,38 с циклом for без очистки данных перед их применением.

Однако я до сих пор не знаю, как использовать черепицу, если существует несколько критериев: Скажем, v является матрицей на 2, а a и b - матрицей m на 2, и мы хотим подсчитать, сколько существует пар (i, к) таким образом, что

(a[j,1]<v[i,1]<b[j,1]) & (a[j,2]<v[i,2]<b[j,2]) 

, что когда (multidimensional-) точек лежит в (multidimensional-) прямоугольники

Смежные вопросы