Я создаю набор данных, который имеет ненулевые значения для b
в качестве первого элемента каждой группы на a
, чтобы проиллюстрировать лучше.В вашем предыдущем наборе данных были все нули, а также c(0,diff(b))
начинался с нуля, поэтому его было трудно дифференцировать.
В данном случае получается, что ifelse
представляет собой вектор длины 1.
library(data.table)
df = data.frame(a = c(1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3),
b = c(10, 1, 0, 1, 0, 1, 1, 0, 3, 4, 5))
Смотрите ниже:
setDT(df)[ , c := ifelse(a >= 3, c(0, diff(b)), b), by = .(a)][]
#> a b c
#> 1: 1 10 10
#> 2: 1 1 10
#> 3: 1 0 10
#> 4: 1 1 10
#> 5: 2 0 0
#> 6: 2 1 0
#> 7: 2 1 0
#> 8: 3 0 0
#> 9: 3 3 0
#> 10: 3 4 0
#> 11: 3 5 0
Теперь давайте посмотрим на некоторые другие примеры;здесь я использую простой вектор длины 4 (вместо c(0,diff(b))
):
setDT(df)[ , c := ifelse(a >= 3L, c(20,2,3,4), -999), by=a][]
#> a b c
#> 1: 1 10 -999
#> 2: 1 1 -999
#> 3: 1 0 -999
#> 4: 1 1 -999
#> 5: 2 0 -999
#> 6: 2 1 -999
#> 7: 2 1 -999
#> 8: 3 0 20
#> 9: 3 3 20
#> 10: 3 4 20
#> 11: 3 5 20
Вы видите, что первый элемент все еще присваивается всем строкам c
для этой группы a
.
Обходное решение использует diff
на a
, чтобы увидеть, когда оно не меняется ( т.е. diff(a)==0
), и использовать это в качестве псевдогруппы вместе сдругое состояние;как показано ниже:
setDT(df)[, c := ifelse(a >= 3 & c(F,diff(a)==0), c(0,diff(b)), b)][]
#> a b c
#> 1: 1 10 10
#> 2: 1 1 1
#> 3: 1 0 0
#> 4: 1 1 1
#> 5: 2 0 0
#> 6: 2 1 1
#> 7: 2 1 1
#> 8: 3 0 0
#> 9: 3 3 3
#> 10: 3 4 1
#> 11: 3 5 1