2013-06-12 7 views
4

У меня есть матрица с очень большим количеством строк и только двумя парными столбцами. Я хочу рассчитать разницу между каждыми строками в столбце 1, и если разница меньше предопределенного значения (.001), тогда вычислите среднее значение этих строк в обоих столбцах. Например, у меня есть матрица под названием веса,Разница между большим количеством строк

A  B 
185.0765 10 
185.3171 20 
186.0777 30 
186.0780 40 
188.0078 50 

weights<-as.data.table(weights) 
bins<-weights[A %between% c(A[3],(A[3]+.001))] 
meanA<-mean(bins$A) 
meanB<-mean(bins$B) 

и результирующая матрица будет,

A  B 
185.0765 10 
185.3171 20 
186.0779 35 
188.0078 50 

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

+0

+1 для ввода данных и желаемого результата и интересной проблемы. –

ответ

6

Это должно добиться того, что вы хотите сделать, используя data.table:

DT <- data.table(weights) 
DT[ , Group :=(cumsum(c(1 , ifelse(diff(weights$A) < 0.001 , 0 , 1)))) ] 
DT[ , lapply(.SD, mean) , by=Group , .SDcols = c("A","B") ] 
# Group  A B 
#1:  1 185.0765 10 
#2:  2 185.3171 20 
#3:  3 186.0779 35 
#4:  4 188.0078 50 

Идея заключается в том, мы используем накопленную сумму, чтобы найти группы A, которые имеют разницу < 0,001. Если разница находится под этим порогом, мы помещаем 0 в наш столбец Group, поэтому в суммарной сумме он будет частью той же группы.

Как было предложено @eddi более емким и эффективный способ сделать это было бы сделать группировку и расчет все в то же время, в одном вызове:

DT <- data.table(weights) 
DT[ , lapply(.SD, mean) , by = list(Group = cumsum(c(1,diff(A)) >= 0.001)) , .SDcols = c("A","B") ]  

Как и в сторону, всегда полезно иметь абсолютное количество строк. A очень большое число строк означает разные вещи для разных людей и прецедентов. Мы говорим миллион? Сотни миллионов?

+2

+1 Это идеальное использование '.SD', поскольку оно использует всю информацию в' .SD'. Основная неэффективность использования '.SD' - это взятие подмножества строк из него; например, 'head (.SD, 2)' расточительно создает все '.SD', хотя нужны только первые 2 строки. Но 'lapply' через' .SD' использует все данные и для чего существует '.SD', особенно с' .SDcols'. –

+0

@MatthewDowle ah ok, я думаю, что я медленно начинаю понимать '.SD' и замечательный пакет' data.table'! (спасибо и шляпку!) –

+0

@ SimonO101 Это сделало трюк. Спасибо за вашу помощь. :) – jsin

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