R сравнение неравных векторов с неравенством

У меня есть два одиночных векторных кадра данных неравной длины

aa<-data.frame(c(2,12,35))
bb<-data.frame(c(1,2,3,4,5,6,7,15,22,36))

Для каждого наблюдения в aa я хочу подсчитать количество случаев, когда bb меньше, чем aa

Мой результат:

   bb<aa 
1   1
2   7
3   9

Я смог сделать это двумя способами, создав функцию и применив ее, но мои наборы данных велики, и я позволяю одному работать всю ночь без конца.

Что я имею:

fun1<-function(a,b){k<-colSums(b<a)
                    k<-k*.000058242}

system.time(replicate(5000,data.frame(apply(aa,1,fun1,b=bb))))
       user  system elapsed 
      3.813   0.011   3.883 

Во-вторых,

fun2<-function(a,b){k<-length(which(b<a))
                    k<-k*.000058242}

system.time(replicate(5000,data.frame(apply(aa,1,fun2,b=bb))))
   user  system elapsed 
  3.648   0.006   3.664 

Вторая функция немного быстрее во всех моих тестах, но я позволил первой работать всю ночь на наборе данных, где bb> 1,7 м и aa> 160 КБ.

Я нашел этот пост, и пытался использовать with(), но, похоже, не смог заставить его работать, а также безуспешно пытался использовать цикл for.

Любая помощь или направление приветствуется.

Благодарю вас!


person Jeff Tilton    schedule 05.12.2014    source источник
comment
Должны ли они быть фреймами данных? Почему не просто векторы? Вы пробовали sapply(aa[[1]],function(x)sum(bb[[1]]<x))? Это было бы лучше, если бы aa и bb были очень векторными.   -  person jlhoward    schedule 05.12.2014
comment
С вектором все в порядке, мои исходные данные были во фрейме данных, но если это можно сделать с двумя векторами, это здорово.   -  person Jeff Tilton    schedule 05.12.2014


Ответы (2)


aa<-data.frame(c(2,12,35))
bb<-data.frame(c(1,2,3,4,5,6,7,15,22,36))
sapply(aa[[1]],function(x)sum(bb[[1]]<x))
# [1] 1 7 9

Еще несколько реальных примеров:

n  <- 1.6e3
bb <- sample(1:n,1.7e6,replace=T)
aa <- 1:n
system.time(sapply(aa,function(x)sum(bb<x)))
#    user  system elapsed 
#   14.63    2.23   16.87 

n  <- 1.6e4
bb <- sample(1:n,1.7e6,replace=T)
aa <- 1:n
system.time(sapply(aa,function(x)sum(bb<x)))
#    user  system elapsed 
#  148.77   18.11  167.26 

Таким образом, с length(aa) = 1.6e4 это занимает около 2,5 минут (в моей системе), а процесс масштабируется как O(length(aa)) — в этом нет ничего удивительного. Таким образом, с вашим полным набором данных он должен работать примерно через 25 минут. Еще как-то медленно. Может быть, кто-то другой придумает лучший способ.

person jlhoward    schedule 05.12.2014
comment
Это сработало! Около 30 минут на моей машине. Любая причина, по которой то, что у вас есть, является лучшим подходом? Я новичок в R и пытаюсь учиться на своих ошибках! Спасибо - person Jeff Tilton; 06.12.2014
comment
Взгляните на Rprof(...) и summaryRprof(...), которые используются для профилирования кода. - person jlhoward; 06.12.2014
comment
Интересно. Я получаю сообщение об ошибке Ошибка: невозможно выделить вектор размером 10,1 Гб Такого раньше не было - person Rich Scriven; 05.01.2015

person    schedule
comment
Вы вообще смотрели на data.table? Я только что сделал это за 0,32 секунды - person Rich Scriven; 05.01.2015
comment
Не уверен, что вы имеете в виду. data.table для чего? Применение функции cdf_land? - person Jeff Tilton; 05.01.2015
comment
Нет, только таблица данных. Я пробежал as.data.table(land_elevation)[, vapply(.I, ">", water_elevation[[1]], 1)], и это было очень быстро - person Rich Scriven; 05.01.2015