And*_*own 4 r data.table tidyverse
我想按组对每一行进行简单的计算,但我需要引用满足某些条件的前一行。我想创建一个新变量,results. 对于每组中的每一行,我想找到上面最接近的行 wheretag == "Y"和codeis not NA。然后,我想使用value该行中的 ,并乘以当前行中的值。
最小的例子
df <- structure(list(name = c("apples", "apples", "apples", "apples",
"oranges", "oranges", "oranges", "oranges"),
id = 1:8,
tag = c("X", "Y", "Y", "X", "X", "Y", "X", "X"),
code = c(1, 1, NA, 1, NA, 1, NA, NA),
value = c(1, 11, 4, 3, 9, 5, 7, 8)),
class = "data.frame", row.names = c(NA, -8L))
name id tag code value
1 apples 1 X 1 1
2 apples 2 Y 1 11
3 apples 3 Y NA 4
4 apples 4 X 1 3
5 oranges 5 X NA 9
6 oranges 6 Y 1 5
7 oranges 7 X NA 7
8 oranges 8 X NA 8
Run Code Online (Sandbox Code Playgroud)
预期输出
例如,对于第 3 行,第 2 行将是最接近满足条件的行,因此将 4 乘以 11(得到 44)。对于第 4 行,第 3 行不满足条件,因此我们转到第 2 行,并将 3 乘以 11(得到 33)。等等。
name id tag code value results
1 apples 1 X 1 1 NA
2 apples 2 Y 1 11 NA
3 apples 3 Y NA 4 44
4 apples 4 X 1 3 33
5 oranges 5 X NA 9 NA
6 oranges 6 Y 1 5 NA
7 oranges 7 X NA 7 35
8 oranges 8 X NA 8 40
Run Code Online (Sandbox Code Playgroud)
我猜我需要使用cumsumand/or fill,但不确定如何在这里使用它。我知道,如果我对前一行执行计算,那么我可以使用lag,但不确定如何搜索上面的多个值。我对基础 R、data.table、tidyverse或其他解决方案持开放态度。
df %>%
group_by(name) %>%
mutate(t = na_if(lag(value * (tag == 'Y' & !is.na(code))), 0)) %>%
fill(t) %>%
mutate(results = t * value)
# A tibble: 8 x 7
# Groups: name [2]
name id tag code value t results
<chr> <int> <chr> <dbl> <dbl> <dbl> <dbl>
1 apples 1 X 1 1 NA NA
2 apples 2 Y 1 11 NA NA
3 apples 3 Y NA 4 11 44
4 apples 4 X 1 3 11 33
5 oranges 5 X NA 9 NA NA
6 oranges 6 Y 1 5 NA NA
7 oranges 7 X NA 7 5 35
8 oranges 8 X NA 8 5 40
Run Code Online (Sandbox Code Playgroud)