2016-12-29 2 views
0

У меня есть набор данных, который выглядит следующим образом (под названием Data):Обнаружение кумулятивный продукта, если определенное условие выполняется в R

v1 v2 
1 1 
1 3 
1 5 
2 3 
2 4 
3 1 
3 2 

Я хочу вернуть вектор v3, что:

  • равна v2 [i], если v1 [i] не равно v1 [i-1]
  • равен v3 [i-1] * v2 [i], если v1 [i] равно v1 [i -1]

Таким образом, в этом примере, v3 должен возвращать

v3 
1 
3 
15 
3 
12 
1 
2 

Я отставал столбец v1, используя lag.v1 < -C (NA, данные [1: nrow (Данные) -1,1]) в для сравнения с предыдущей строкой. Я думаю, что что-то похожее на следующее должно работать, но со значением v3 в предыдущей строке вместо текущей строки.

данных $ v3 < -ifelse (1 * (Data $ v1 == lag.v1) == 1, данные $ v3 * Данные $ v2, данные $ v2)

Другими словами, мне нужно каким-то образом получить доступ к предыдущей строке v3 (lag v3), поскольку я формирую v3 в приведенном выше уравнении.

справка приветствуется, спасибо!

ответ

1

Вы можете использовать ave с cumprod, это вычисляет совокупный продукт колонны v2, сгруппированные по v1:

df$v3 <- with(df, ave(v2, v1, FUN=cumprod)) 

df 
# v1 v2 v3 
#1 1 1 1 
#2 1 3 3 
#3 1 5 15 
#4 2 3 3 
#5 2 4 12 
#6 3 1 1 
#7 3 2 2 

С plyr пакета, вы можете использовать ddply с transform:

plyr::ddply(df, "v1", transform, v3 = cumprod(v2)) 

# v1 v2 v3 
#1 1 1 1 
#2 1 3 3 
#3 1 5 15 
#4 2 3 3 
#5 2 4 12 
#6 3 1 1 
#7 3 2 2 

Если нет, то вы, вероятно, также хотят знать dplyr подход:

library(dplyr) 
df %>% group_by(v1) %>% mutate(v3 = cumprod(v2)) 

#Source: local data frame [7 x 3] 
#Groups: v1 [3] 

#  v1 v2 v3 
# <int> <int> <dbl> 
#1  1  1  1 
#2  1  3  3 
#3  1  5 15 
#4  2  3  3 
#5  2  4 12 
#6  3  1  1 
#7  3  2  2 
+0

Можно ли использовать метод авеню и группу на 2 разных колонках? – user7352235

+0

Вы можете передать более чем одну переменную группы в ave после вектора значений. Например, если у вас есть переменные 'g1',' g2' и есть столбец значений как 'v', то вы можете делать' с помощью (df, ave (v, g1, g2, FUN = cumprod)) '. – Psidom

+0

Получил, спасибо! – user7352235

0

Мы можем использовать data.table

library(data.table) 
setDT(df)[, v3 := cumprod(v2), by = v1] 
df 
# v1 v2 v3 
#1: 1 1 1 
#2: 1 3 3 
#3: 1 5 15 
#4: 2 3 3 
#5: 2 4 12 
#6: 3 1 1 
#7: 3 2 2 
+0

Это помогает, спасибо. Можно ли группировать по 2 разных столбца? Как и в, значение должно быть одинаковым в обоих столбцах, чтобы взять cumprod. – user7352235

+0

@ user7352235 Да, вы можете сделать это с помощью 'setDT (df) [, v3: = cumprod (v2), by =. (Col1, col2)]' – akrun

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