Суммировать строки и добавить к следующей строке в R

Я хотел бы суммировать строки в Col1, для которых Col2 равен 0. И добавить сумму к следующему значению в Col1. Я показываю пример ниже. У меня есть много продуктов в фрейме данных. Я начал с этого:

library(dplyr)

TD %>% group_by(Product,Date) %>% mutate(Sum = sum(Col1[Col2 == 0])[1]) %>% 
  mutate(Expected = Col1)

Date <- seq(as.Date("2021-01-01"), as.Date("2021-01-07"), by = "day")
Product<-rep("A",7)
Col1 <- c(13, 10, 15, 7, 9, 4, 3)
Col2 <- c(7, 0, 0, 8, 0, 0, 27)
Expected <- c(13, 10, 15, 32, 9, 4, 16)
TD <- data.frame(Date, Product, Col1, Col2, Expected)

Другие данные:

   Date       Product   Col1  Col2 Expected2
   <date>     <chr>   <dbl>  <dbl>     <dbl>
 1 2021-02-12 831        15    384       631
 2 2021-02-13 831        11    373       631
 3 2021-02-14 831        13    360       631
 4 2021-02-15 831        14    826       631
 5 2020-12-03 832        10     11        20
 6 2020-12-04 832        10      1        20
 7 2020-12-05 832         7      0         7
 8 2020-12-06 832        11      0        11
 9 2020-12-07 832        13      0        13
10 2020-12-08 832        10      0        10



structure(list(Date = structure(c(18670, 18671, 18672, 18673, 
18599, 18600, 18601, 18602, 18603, 18604, 18605, 18606, 18607, 
18608, 18609, 18610, 18611, 18612, 18613, 18614, 18615, 18616, 
18617, 18618, 18619, 18620, 18621, 18622, 18623, 18624), class = "Date"), 
    Product = c("831", "831", "831", "831", "832", "832", "832", 
    "832", "832", "832", "832", "832", "832", "832", "832", "832", 
    "832", "832", "832", "832", "832", "832", "832", "832", "832", 
    "832", "832", "832", "832", "832"), Col1 = c(15, 11, 13, 
    14, 10, 10, 7, 11, 13, 10, 8, 11, 9, 8, 10, 17, 15, 17, 16, 
    16, 14, 14, 15, 17, 18, 16, 17, 18, 18, 8), Col2 = c(384, 
    373, 360, 826, 11, 1, 0, 0, 0, 0, 0, 70, 61, 53, 43, 26, 
    11, 0, 0, 84, 70, 56, 41, 24, 6, 0, 0, 0, 0, 0), Expected2 = c(631, 
    631, 631, 631, 20, 20, 7, 11, 13, 10, 8, 119, 119, 119, 119, 
    119, 119, 17, 16, 127, 127, 127, 127, 127, 127, 16, 17, 18, 
    18, 8)), row.names = c(NA, -30L), class = c("tbl_df", "tbl", 
"data.frame"))

что ожидается для этих новых данных

akrun 10.12.2020 01:03

То же, что и Col1, потому что Col2 не содержит нулей.

Zizou 10.12.2020 01:05

@akrun Я добавляю новые данные.

Zizou 10.12.2020 01:37

Мне нужно создать данные вручную, чтобы проверить их. На этом сработало. Пожалуйста, проверьте ТД3

akrun 10.12.2020 01:38

В ваших новых данных последняя строка равна 0, поэтому она не должна получать значение суммы, верно?

akrun 10.12.2020 01:40

Я просто вырезал данные, чтобы последняя строка была нулевой. Но код работает очень хорошо.

Zizou 10.12.2020 01:45

Я обновил пост. Он должен работать во всех этих случаях. Пожалуйста, проверьте обновленный код на всех примерах, которые я обновляю

akrun 10.12.2020 01:47

Давайте продолжим обсуждение в чате.

Zizou 10.12.2020 01:53
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
8
133
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем

library(dplyr)    
TD %>%
   group_by(Product) %>%
   group_by(grp = cumsum(lag(Col2 != 0, default = FALSE)), .add = TRUE) %>% 
   mutate(Expected2 = sum(Col1)) %>%
   group_by(Product) %>%     
   mutate(Expected2 = case_when(Col2 == 0 | !any(Col2 == 0) ~
       Col1, TRUE ~ Expected2)) %>%
  ungroup %>% 
  select(-grp)

-выход

# A tibble: 7 x 6
#  Date       Product  Col1  Col2 Expected Expected2
#  <date>     <chr>   <dbl> <dbl>    <dbl>     <dbl>
#1 2021-01-01 A          13     7       13        13
#2 2021-01-02 A          10     0       10        10
#3 2021-01-03 A          15     0       15        15
#4 2021-01-04 A           7     8       32        32
#5 2021-01-05 A           9     0        9         9
#6 2021-01-06 A           4     0        4         4
#7 2021-01-07 A           3    27       16        16

-тестирование на втором наборе данных

TD2 %>%
     group_by(Product) %>%
     group_by(grp = cumsum(lag(Col2 != 0, default = FALSE)), .add = TRUE)%>% 
     mutate(tmp = sum(Col1), Expected2 = case_when(any(Col2 == 0) & 
        (row_number() == n() & Col2 != 0) ~ tmp, TRUE ~ Col1)) %>%
     ungroup %>%
     select(-grp, -tmp)

-выход

# A tibble: 15 x 5
#   Date                Product  Col1  Col2 Expected2
#   <chr>               <chr>   <int> <int>     <int>
# 1 2020-12-03 00:00:00 B          10   206        10
# 2 2020-12-04 00:00:00 B           5   364         5
# 3 2020-12-05 00:00:00 B          10   354        10
# 4 2020-12-06 00:00:00 B           8   346         8
# 5 2020-12-07 00:00:00 B           5   341         5
# 6 2020-12-08 00:00:00 B           8   333         8
# 7 2020-12-09 00:00:00 B          12   321        12
# 8 2020-12-10 00:00:00 B           5   316         5
# 9 2020-12-11 00:00:00 B           7   309         7
#10 2020-12-12 00:00:00 B          13   296        13
#11 2020-12-13 00:00:00 B           9   287         9
#12 2020-12-14 00:00:00 B          11   276        11
#13 2020-12-15 00:00:00 B          10   266        10
#14 2020-12-16 00:00:00 B          17   249        17
#15 2020-12-17 00:00:00 B          14   235        14

Или данные изображения

TD3 %>%
    group_by(Product) %>%
    group_by(grp = cumsum(lag(Col2 != 0, default = FALSE)), .add = TRUE) %>%
    mutate(tmp = sum(Col1), Expected2 = case_when(any(Col2 == 0) & 
       (row_number() == n() & Col2 != 0) ~ tmp, TRUE ~ Col1)) %>%
    ungroup %>%
    select(-grp, -tmp)

-выход

# A tibble: 21 x 4
#   Product  Col1  Col2 Expected2
#   <chr>   <dbl> <dbl>     <dbl>
# 1 C          11    52        11
# 2 C           7    45         7
# 3 C           6    39         6
# 4 C          15    24        15
# 5 C          14    10        14
# 6 C          10     0        10
# 7 C           8     0         8
# 8 C          10   125        28
# 9 C          12   113        12
#10 C          11   102        11
# … with 11 more rows

Или используя последние dput данные OP

 TD4 %>%
     group_by(Product) %>%
     group_by(grp = cumsum(lag(Col2 != 0, default = FALSE)), .add = TRUE) %>%
     mutate(tmp = sum(Col1), Expected2 = case_when(any(Col2 == 0) & 
        (row_number() == n() & Col2 != 0) ~ tmp, TRUE ~ Col1)) %>%
     ungroup %>%
     select(-grp, -tmp) %>%
     as.data.frame

-выход

#         Date Product Col1 Col2 Expected2
#1  2021-02-12     831   15  384        15
#2  2021-02-13     831   11  373        11
#3  2021-02-14     831   13  360        13
#4  2021-02-15     831   14  826        14
#5  2020-12-03     832   10   11        10
#6  2020-12-04     832   10    1        10
#7  2020-12-05     832    7    0         7
#8  2020-12-06     832   11    0        11
#9  2020-12-07     832   13    0        13
#10 2020-12-08     832   10    0        10
#11 2020-12-09     832    8    0         8
#12 2020-12-10     832   11   70        60
#13 2020-12-11     832    9   61         9
#14 2020-12-12     832    8   53         8
#15 2020-12-13     832   10   43        10
#16 2020-12-14     832   17   26        17
#17 2020-12-15     832   15   11        15
#18 2020-12-16     832   17    0        17
#19 2020-12-17     832   16    0        16
#20 2020-12-18     832   16   84        49
#21 2020-12-19     832   14   70        14
#22 2020-12-20     832   14   56        14
#23 2020-12-21     832   15   41        15
#24 2020-12-22     832   17   24        17
#25 2020-12-23     832   18    6        18
#26 2020-12-24     832   16    0        16
#27 2020-12-25     832   17    0        17
#28 2020-12-26     832   18    0        18
#29 2020-12-27     832   18    0        18
#30 2020-12-28     832    8    0         8

данные

TD2 <- structure(list(Date = c("2020-12-03 00:00:00", "2020-12-04 00:00:00", 
"2020-12-05 00:00:00", "2020-12-06 00:00:00", "2020-12-07 00:00:00", 
"2020-12-08 00:00:00", "2020-12-09 00:00:00", "2020-12-10 00:00:00", 
"2020-12-11 00:00:00", "2020-12-12 00:00:00", "2020-12-13 00:00:00", 
"2020-12-14 00:00:00", "2020-12-15 00:00:00", "2020-12-16 00:00:00", 
"2020-12-17 00:00:00"), Product = c("B", "B", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B"), Col1 = c(10L, 
5L, 10L, 8L, 5L, 8L, 12L, 5L, 7L, 13L, 9L, 11L, 10L, 17L, 14L
), Col2 = c(206L, 364L, 354L, 346L, 341L, 333L, 321L, 316L, 309L, 
296L, 287L, 276L, 266L, 249L, 235L), Expected2 = c(144L, 144L, 
144L, 144L, 144L, 144L, 144L, 144L, 144L, 144L, 144L, 144L, 144L, 
144L, 144L)), class = "data.frame", row.names = c("1", "2", "3", 
"4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15"
))




TD3 <- structure(list(Product = c("C", "C", "C", "C", "C", "C", "C", 
"C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", 
"C"), Col1 = c(11, 7, 6, 15, 14, 10, 8, 10, 12, 11, 10, 20, 20, 
22, 19, 23, 21, 20, 26, 26, 27), Col2 = c(52, 45, 39, 24, 10, 
0, 0, 125, 113, 102, 92, 72, 52, 30, 11, 138, 117, 97, 71, 45, 
18)), class = "data.frame", row.names = c(NA, -21L))
mutate(Expected2 = sum(Expected))? но у меня нет столбца Ожидается раньше. Я хочу получить столбец Ожидается.
Zizou 10.12.2020 00:32

Вы можете помочь мне?

Zizou 10.12.2020 00:40

@Zizou обновил пост. Это опечатка, я раньше не заметил

akrun 10.12.2020 00:49

Я понимаю, но ваш код плохо работает с моими данными

Zizou 10.12.2020 00:57

@Zizou, это данные, которые вы разместили в качестве примера, и они работают для меня.

akrun 10.12.2020 00:58

Добавьте другие данные для вашего кода, вы видите?

Zizou 10.12.2020 01:03

@Zizou да, но у него нет столбца Expected

akrun 10.12.2020 01:03

То же, что и Col1, потому что Col2 не содержит нулей.

Zizou 10.12.2020 01:06

@Zizou Я думаю, нам нужно условие, если нет нулей

akrun 10.12.2020 01:07

@Zizou Неясно, есть ли в ваших данных 0 или нет. Можете ли вы показать пример с обоими случаями для тестирования

akrun 10.12.2020 01:09

Некоторые продукты имеют нули, а некоторые нет.

Zizou 10.12.2020 01:11

Я добавляю новый образец на картинке на главной странице.

Zizou 10.12.2020 01:21

Давайте продолжим обсуждение в чате.

Zizou 10.12.2020 01:24

Другие вопросы по теме