我的数据框看起来像这样:
> df
# A tibble: 5,427 x 3
cond desired inc
<chr> <dbl> <dbl>
1 <NA> 0 0
2 <NA> 5 5
3 X 10 5
4 X 7 7
5 <NA> 16 16
6 <NA> 21 5
7 <NA> 26 5
8 <NA> 31 5
9 X 37 6
10 <NA> 5 5
这已经包含了我想要的输出。我想要做的是总结inc
的值,但如果前一行的X
- 列中有cond
,则重置总和。例如,在行9
中,我将从上一行(31)中获取desired
- 值并添加inc
- 来自行9
(6)的值。在行5
中,我只取inc
- 值,因为前一行的cond
- 列为X
。我使用循环解决了这个问题,但我想使用矢量化解决方案。到目前为止我得到了这个:
df$test <- 0
df <- df %>% mutate(test = ifelse(is.na(lag(df$cond)), lag(test) + inc, inc))
如果我得到这个,我会跑第二行:
> df
# A tibble: 5,427 x 4
cond desired inc test
<chr> <dbl> <dbl> <dbl>
1 <NA> 0 0 NA
2 <NA> 5 5 5
3 X 10 5 5
4 X 7 7 7
5 <NA> 16 16 16
6 <NA> 21 5 5
7 <NA> 26 5 5
8 <NA> 31 5 5
9 X 37 6 6
10 <NA> 5 5 5
第二次运行后,它看起来像这样:
> df
# A tibble: 5,427 x 4
cond desired inc test
<chr> <dbl> <dbl> <dbl>
1 <NA> 0 0 NA
2 <NA> 5 5 NA
3 X 10 5 10
4 X 7 7 7
5 <NA> 16 16 16
6 <NA> 21 5 21
7 <NA> 26 5 10
8 <NA> 31 5 10
9 X 37 6 11
10 <NA> 5 5 5
# ... with 5,417 more rows
第三次:
> df
# A tibble: 5,427 x 4
cond desired inc test
<chr> <dbl> <dbl> <dbl>
1 <NA> 0 0 NA
2 <NA> 5 5 NA
3 X 10 5 NA
4 X 7 7 7
5 <NA> 16 16 16
6 <NA> 21 5 21
7 <NA> 26 5 26
8 <NA> 31 5 15
9 X 37 6 16
10 <NA> 5 5 5
然后,在第五次之后:
> df
# A tibble: 5,427 x 4
cond desired inc test
<chr> <dbl> <dbl> <dbl>
1 <NA> 0 0 NA
2 <NA> 5 5 NA
3 X 10 5 NA
4 X 7 7 7
5 <NA> 16 16 16
6 <NA> 21 5 21
7 <NA> 26 5 26
8 <NA> 31 5 31
9 X 37 6 37
10 <NA> 5 5 5
我正在使用我在mutate-command本身中使用mutate创建的列,我想这会导致此行为/问题。有没有办法达到我想要的结果?提前谢谢!
数据框:
structure(list(cond = c(NA, NA, "X", "X", NA, NA, NA, NA, "X",
NA, NA, NA, NA, NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, "X",
NA, NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA, "X", NA, NA, "X",
NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA, "X", NA,
NA, NA, NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA,
NA, "X", NA, NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA,
NA, NA, NA, "X", NA, NA, NA, "X", NA, NA, NA, NA, "X", NA, NA,
NA, NA, NA, NA, NA, NA, "X", NA, NA, "X", NA, NA, NA, NA, "X",
NA, NA, NA, NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA,
NA, "X", NA, "X", NA, NA, NA, NA, NA, NA, NA, NA, "X", NA, NA,
NA, NA, NA, NA, NA, "X", NA, NA, NA, "X", "X", NA, NA, NA, NA,
NA, NA, NA, NA, "X", "X", NA, "X", NA, NA, NA, NA, NA, NA, NA,
NA, "X", NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA, NA, "X",
NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, "X", NA, NA, NA, NA,
"X", NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, NA, NA, NA, NA,
"X", NA, NA, NA, NA, NA, NA, "X", NA, NA, NA, NA, "X", NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "X", NA, "X",
NA, "X", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, "X", NA, NA, NA), desired = c(0, 5, 10, 7, 16, 21, 26,
31, 37, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 5, 10, 15, 20,
30, 7, 15, 21, 25, 40, 45, 55, 12, 20, 25, 30, 35, 40, 45, 50,
55, 60, 65, 70, 75, 5, 10, 15, 20, 22, 30, 35, 45, 50, 55, 60,
65, 70, 75, 9, 14, 19, 24, 29, 34, 39, 44, 5, 7, 10, 2, 7, 12,
17, 22, 27, 5, 10, 15, 20, 25, 30, 35, 38, 4, 7, 12, 17, 22,
27, 32, 37, 39, 13, 18, 23, 28, 33, 38, 43, 48, 53, 5, 10, 15,
20, 25, 30, 35, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 5, 10,
15, 20, 2, 10, 15, 20, 25, 5, 10, 15, 20, 25, 30, 35, 40, 45,
5, 8, 12, 5, 10, 14, 19, 24, 5, 10, 15, 20, 25, 30, 35, 40, 45,
5, 10, 15, 20, 25, 28, 33, 38, 5, 11, 5, 10, 15, 20, 25, 30,
35, 40, 45, 12, 17, 22, 27, 32, 37, 42, 47, 5, 10, 15, 20, 5,
5, 10, 15, 20, 25, 30, 35, 40, 45, 5, 5, 10, 5, 10, 15, 20, 25,
30, 35, 40, 45, 5, 10, 15, 20, 5, 10, 15, 20, 25, 30, 34, 39,
44, 5, 10, 15, 20, 25, 30, 5, 10, 15, 20, 25, 5, 10, 15, 20,
25, 5, 10, 15, 20, 25, 29, 5, 10, 15, 20, 23, 25, 30, 35, 40,
5, 15, 20, 25, 30, 35, 40, 5, 10, 15, 20, 25, 5, 10, 15, 20,
25, 28, 33, 38, 43, 48, 53, 58, 71, 76, 81, 5, 10, 5, 10, 5,
10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 5,
10, 15), inc = c(0, 5, 5, 7, 16, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 10, 7, 8, 6, 4, 15, 5, 10, 12, 8, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 8, 5, 10, 5, 5,
5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 5, 5, 5, 2, 3, 2, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 3, 4, 3, 5, 5, 5, 5, 5, 5, 2, 13, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 2, 8, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3, 4, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
3, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,
5, 5, 5, 5, 3, 2, 5, 5, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 13, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5)), .Names = c("cond",
"desired", "inc"), row.names = c(NA, -300L), class = c("tbl_df",
"tbl", "data.frame"))
答案 0 :(得分:7)
以下是使用ave()
函数和上面的df结构的示例。我清楚地展示了所有步骤,但如果需要,可以减少这些步骤。
library(dplyr)
df %>%
mutate(prevcond = lag(cond)) %>%
mutate(flag = ifelse(is.na(prevcond) | prevcond !='X', 0, 1)) %>%
mutate(counter = cumsum(flag)) %>%
mutate(desired2 = ave(inc, counter, FUN = cumsum))
答案 1 :(得分:4)
要获得所需的输出,我们必须首先创建一个分组列,每当前一行等于X
时重置。为此,我们将row_number()
与zoo::na.locf()
结合使用。然后我们可以简单地使用cumsum()
:
library(dplyr)
library(zoo)
df %>% group_by(grp = na.locf(row_number(cond),
fromLast = TRUE,
na.rm = FALSE)) %>%
mutate(test = cumsum(inc))
# cond desired inc grp test
# <chr> <dbl> <dbl> <int> <dbl>
# 1 <NA> 0 0 1 0
# 2 <NA> 5 5 1 5
# 3 X 10 5 1 10
# 4 X 7 7 2 7
# 5 <NA> 16 16 3 16
# 6 <NA> 21 5 3 21
# 7 <NA> 26 5 3 26
# 8 <NA> 31 5 3 31
# 9 X 37 6 3 37
#10 <NA> 5 5 4 5