2016-07-25 2 views
1

У меня есть DataFrame DF, который имеет следующие данные; около 300000 строкУмножить строки в 2 столбцах, группируя помеченные строки в R

<DF 
A B C 
1 2 0 
2 5 0 
4 5 2 
4 7 0 
7 8 0 
9 7 -2 
2 5 0 
4 7 0 
5 1 2 
4 7 0 
7 8 0 
9 7 -2 
2 5 0 
4 7 0 
5 1 2 

Я хочу, чтобы выполнить математическую операцию по набору данных со следующей логикой

Select all rows till first occurrence of 2 in C(ignoring -2 in the middle)

Compute avg of all these of (A*B) and add it column D (Implying all these rows in column D will have the same value)

Select all rows from first occurrence of 2 till the second occurrence

Compute avg of (A*B) for these rows and add it column D

... Do the same till

Select all rows from last occurrence of 2 till the second last occurrence

Compute avg of (A*B) for these rows and add it column D

Результат должен выглядеть

<Result 
A B C D 
1 2 0 6 
2 5 0 6 
4 5 2 34.16667 
4 7 0 34.16667 
7 8 0 34.16667 
9 7 -2 34.16667 
2 5 0 34.16667 
4 7 0 34.16667 
5 1 2 27.85714 
4 7 0 27.85714 
7 8 0 27.85714 
9 7 -2 27.85714 
2 5 0 27.85714 
4 7 0 27.85714 
5 1 2 NA 

Как реализовать эту логику в Р? Заранее спасибо!

+1

Добро пожаловать в СО, пожалуйста, будьте немного более конкретными, задавая вопрос: что вы пробовали, чего вы ожидаете и т. Д. См. [Как спросить] (http://stackoverflow.com/help/how -to-ask) – Nehal

+0

Всегда, попробуйте включить воспроизводимый пример .. – Prradep

ответ

1

Вот вариант с data.table. Преобразование «data.frame» к «data.table» (setDT(DF)), сгруппированных по кумулятивной сумме логического вектора (C==2), мы получаем mean из A * B и умножить на значения генерируемых NA^(.N==1) (.N==1 возвращает логический вектор из TRUE/FALSE для количества строк, равных 1 или нет, и используя NA^ преобразует это в NA/1), так что все группы, которые имеют только один элемент, возвращают NA, а другие имеют mean(A*B).

library(data.table) 
setDT(DF)[, D := NA^(.N==1)*mean(A*B) , .(grp = cumsum(C==2))] 
DF 
# A B C  D 
# 1: 1 2 0 6.00000 
# 2: 2 5 0 6.00000 
# 3: 4 5 2 34.16667 
# 4: 4 7 0 34.16667 
# 5: 7 8 0 34.16667 
# 6: 9 7 -2 34.16667 
# 7: 2 5 0 34.16667 
# 8: 4 7 0 34.16667 
# 9: 5 1 2 31.66667 
#10: 4 7 0 31.66667 
#11: 7 8 0 31.66667 
#12: 9 7 -2 31.66667 
#13: 2 5 0 31.66667 
#14: 4 7 0 31.66667 
#15: 5 1 2  NA 
+1

Эй! Спасибо @akrun, это было безупречно! –

1

Использование dplyr,

library(dplyr) 
df <- df %>% 
     mutate(ind = cumsum(C == 2)) %>% 
     group_by(ind) %>% 
     mutate(D = mean(A*B), D = replace(D, n() == 1, NA)) 
+0

Также, как добавить столбец D, который я могу получить здесь, в исходный фреймворк? –

+0

вам нужно назначить его df ... см. Edit – Sotos

+1

Это работало, как ветер! Спасибо за сохранение моего дня @Satos –

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