Сумма в одном столбце в зависимости от количества вхождений значений из другого столбца - PullRequest
0 голосов
/ 29 мая 2020

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

У меня есть данные о запасах, которые выглядят примерно так:

"DateTime","Price","Volume","Group"
2020-05-01 13:30:01.354,174.003,750,2020-05-01
2020-05-01 13:30:01.454,174.003,750,2020-05-01
2020-05-01 13:30:01.612,174.592,750,2020-05-01
2020-05-01 13:30:01.663,174.812,750,2020-05-01
2020-05-01 13:30:01.775,174.742,750,2020-05-01
2020-05-01 13:30:02.090,174.742,2000.0001,2020-05-01
2020-05-01 13:30:02.139,174.742,750,2020-05-01
2020-05-01 13:30:02.190,174.743,2000.0001,2020-05-01
2020-05-01 13:30:02.308,174.612,2000.0001,2020-05-01
2020-05-01 13:30:02.428,174.612,750,2020-05-01
2020-05-01 13:30:02.554,174.522,2000.0001,2020-05-01
2020-05-01 13:30:02.656,174.552,750,2020-05-01
2020-05-01 13:30:02.705,174.522,2000.0001,2020-05-01
2020-05-01 13:30:02.913,174.645,750,2020-05-01
2020-05-01 13:30:02.963,175.002,750,2020-05-01
2020-05-01 13:30:03.013,175.002,2000.0001,2020-05-01
2020-05-01 13:30:03.125,175.002,750,2020-05-01
2020-05-01 13:30:03.312,174.803,750,2020-05-01
2020-05-01 13:30:03.362,175.002,2000.0001,2020-05-01
2020-05-01 13:30:03.876,174.772,750,2020-05-01
2020-05-01 13:30:03.927,174.802,2000.0001,2020-05-01
2020-05-01 13:30:04.052,174.802,2000.0001,2020-05-01
2020-05-01 13:30:04.154,174.692,750,2020-05-01
2020-05-01 13:30:04.203,174.802,750,2020-05-01
2020-05-01 13:30:04.255,174.803,2000.0001,2020-05-01
2020-05-01 13:30:04.304,174.803,2000.0001,2020-05-01
2020-05-01 13:30:04.404,174.802,750,2020-05-01
2020-05-01 13:30:04.455,175.003,2000.0001,2020-05-01
2020-05-01 13:30:04.521,174.803,750,2020-05-01
2020-05-01 13:30:04.649,174.802,750,2020-05-01
2020-05-01 13:30:04.771,174.803,2000.0001,2020-05-01
2020-05-01 13:30:04.822,174.803,2000.0001,2020-05-01
2020-05-01 13:30:04.899,174.702,750,2020-05-01
2020-05-01 13:30:04.950,174.802,750,2020-05-01
2020-05-01 13:30:06.498,174.722,750,2020-05-01
2020-05-01 13:30:07.794,174.723,750,2020-05-01
2020-05-01 13:30:07.843,175.003,2000.0001,2020-05-01
2020-05-01 13:30:08.095,175.002,750,2020-05-01
2020-05-01 13:30:08.466,175.002,750,2020-05-01
2020-05-01 13:30:08.567,175.002,750,2020-05-01
2020-05-01 13:30:08.743,174.982,2000.0001,2020-05-01
2020-05-01 13:30:09.123,175.002,750,2020-05-01
2020-05-01 13:30:09.381,174.982,750,2020-05-01
2020-05-01 13:30:09.893,175.002,750,2020-05-01
2020-05-01 13:30:09.942,174.882,750,2020-05-01
2020-05-01 13:30:09.993,174.962,750,2020-05-01
2020-05-01 13:30:11.404,175.002,2000.0001,2020-05-01
2020-05-01 13:30:11.716,174.963,750,2020-05-01
2020-05-01 13:30:11.932,174.963,750,2020-05-01
2020-05-01 13:30:11.983,175.002,750,2020-05-01
2020-05-01 13:30:12.038,174.962,750,2020-05-01
2020-05-01 13:30:12.414,174.963,2000.0001,2020-05-01
2020-05-01 13:30:12.533,174.863,750,2020-05-01
2020-05-01 13:30:12.585,174.962,2000.0001,2020-05-01
2020-05-01 13:30:13.763,175.002,750,2020-05-01
2020-05-01 13:30:14.473,174.962,750,2020-05-01
2020-05-01 13:30:16.157,174.962,750,2020-05-01
2020-05-01 13:30:16.207,175.002,2000.0001,2020-05-01
2020-05-01 13:30:16.268,175.002,750,2020-05-01
2020-05-01 13:30:18.455,175.002,750,2020-05-01
2020-05-01 13:30:18.506,175.322,750,2020-05-01
2020-05-01 13:30:19.289,175.322,750,2020-05-01
2020-05-01 13:30:19.340,175.342,750,2020-05-01
2020-05-01 13:30:19.953,175.343,750,2020-05-01
2020-05-01 13:30:20.761,175.362,2000.0001,2020-05-01
2020-05-01 13:30:21.588,175.363,750,2020-05-01
2020-05-01 13:30:21.638,175.382,750,2020-05-01
2020-05-01 13:30:22.387,175.383,750,2020-05-01
2020-05-01 13:30:22.486,175.442,750,2020-05-01
2020-05-01 13:30:22.580,175.382,750,2020-05-01
2020-05-01 13:30:23.595,175.442,750,2020-05-01
2020-05-01 13:30:23.645,175.383,750,2020-05-01
2020-05-01 13:30:23.762,175.442,750,2020-05-01
2020-05-01 13:30:24.085,175.382,750,2020-05-01
2020-05-01 13:30:24.134,175.273,2000.0001,2020-05-01
2020-05-01 13:30:24.608,175.272,750,2020-05-01
2020-05-01 13:30:24.658,175.272,750,2020-05-01
2020-05-01 13:30:25.019,175.272,750,2020-05-01
2020-05-01 13:30:25.070,175.332,750,2020-05-01
2020-05-01 13:30:25.238,175.283,750,2020-05-01
2020-05-01 13:30:25.289,175.282,2000.0001,2020-05-01
2020-05-01 13:30:25.749,175.273,750,2020-05-01
2020-05-01 13:30:25.799,175.273,2000.0001,2020-05-01
2020-05-01 13:30:25.863,175.273,750,2020-05-01
2020-05-01 13:30:25.914,175.333,2000.0001,2020-05-01
2020-05-01 13:30:26.073,175.283,750,2020-05-01
2020-05-01 13:30:26.124,175.282,2000.0001,2020-05-01
2020-05-01 13:30:26.187,175.203,750,2020-05-01
2020-05-01 13:30:26.237,175.182,2000.0001,2020-05-01
2020-05-01 13:30:26.710,175.282,2000.0001,2020-05-01
2020-05-01 13:30:27.511,175.282,2000.0001,2020-05-01
2020-05-01 13:30:27.763,175.332,2000.0001,2020-05-01
2020-05-01 13:30:28.187,175.233,750,2020-05-01
2020-05-01 13:30:28.236,175.232,750,2020-05-01
2020-05-01 13:30:28.302,175.232,750,2020-05-01
2020-05-01 13:30:28.353,175.232,2000.0001,2020-05-01
2020-05-01 13:30:28.457,175.152,750,2020-05-01
2020-05-01 13:30:28.507,175.152,750,2020-05-01
2020-05-01 13:30:28.601,175.153,2000.0001,2020-05-01
2020-05-01 13:30:28.894,175.093,750,2020-05-01
2020-05-01 13:30:28.945,175.092,750,2020-05-01
2020-05-01 13:30:29.049,175.093,2000.0001,2020-05-01

Я хотел рассчитать cumsum для Volume на основе последовательных частот значений в Price столбец. Ниже приведен пример r вывода вышеуказанного csv как data.frame/data.table.

                  DateTime   Price Volume      Group
 1: 2020-05-01 13:30:01.354 174.003    750 2020-05-01
 2: 2020-05-01 13:30:01.454 174.003    750 2020-05-01
 3: 2020-05-01 13:30:01.612 174.592    750 2020-05-01
 4: 2020-05-01 13:30:01.663 174.812    750 2020-05-01
 5: 2020-05-01 13:30:01.775 174.742    750 2020-05-01
 6: 2020-05-01 13:30:02.090 174.742   2000 2020-05-01
 7: 2020-05-01 13:30:02.139 174.742    750 2020-05-01
 8: 2020-05-01 13:30:02.190 174.743   2000 2020-05-01
 9: 2020-05-01 13:30:02.308 174.612   2000 2020-05-01
10: 2020-05-01 13:30:02.428 174.612    750 2020-05-01
 8: 2020-05-01 13:30:02.554 174.522   2000 2020-05-01
 9: 2020-05-01 13:30:02.656 174.552   2000 2020-05-01
10: 2020-05-01 13:30:02.705 174.522    750 2020-05-01

Чтобы объяснить более подробно, я возьму первые 2 строки и суммирую их соответствующие объемы в один элемент объект выходных данных (желательно data.frame); цены в строке 3 и строке 4 имеют частоту 1 (уникальное вхождение в ценовом ряду), поэтому их объемы не нужно суммировать, и в объекте выходных данных будет получено 2 строки. цена для строки 5,6,7 была той же 174,742, тогда я бы снова суммировал 3 тома и создал 1 строку в объекте выходных данных. Тот же лог c применим и к остальным данным.

Я экспериментировал с dplyr, но безрезультатно; лучшее, что я мог получить, - это группы индексов для каждого события цены, но естественный порядок не мог быть сохранен. Я не могу придумать способ даже приблизиться к результату, который я хотел (в векторизованном стиле я пытался избежать простого цикла и написания слишком большого количества logi c).

, как было предложено @RonakShah Я добавлю этот ожидаемый пример вывода. Извините, я не добавил его раньше, потому что я действительно не знал, как он будет выглядеть. Но, как я подумал еще раз, я думаю, мне просто нужен вывод для последовательности томов cumsum в виде одного столбца. Мне действительно не нужен другой столбец для индексации (хотя, по-видимому, любой дополнительный столбец будет очень полезен).

Пример вывода:

         Cumsum.Volume
    1:       1500  # aggregated from row 1,2 as they have same price
    2:       750   # no aggregation as row 3 has occurred only once
    3:       750   # same as above
    4:       3500  # aggregation from row 4,5,6 as they have the same price
    5:       2000  # row 7 no aggregation for unique price occurrence in sequence
    6:       2750  # row 8,9 maps to same price so add them up
    7:       2000  # row 10 needs no aggregation
    8:       2000  # row 11 needs no aggregation
    9:       750   # row 12 needs no aggregation

Вот сопоставление между цена и объем:

`174.003` appeared twice together, so we cumsum their volumes
`174.592` appeared by itself, so we keep its volume
`174.812` appeared by itself, so we keep its volume
`174.742` appeared 3 times consecutively, so we cumsum/aggregate their volumes
`174.743` appeared by itself, so we keep its volume
`174.612` appeared twice together, so we cumsum their volumes
`174.522` appeared once by itself, we keep its volume
`174.552` appeared by itself, we keep its volume
`174,522` appeared again by itself, we keep its volume

Я надеюсь, что вышеупомянутое дополнение может дать вам лучшее представление; порядок объема cumsum соответствовал естественному порядку столбца цены, но мне не нужно сохранять столбец цены.

Есть какие-нибудь подсказки в правильном направлении?

Ответы [ 2 ]

1 голос
/ 29 мая 2020

Группировать по дате, составляющей DateTime, и Price

library(tidyverse)

data <- tibble(
          DateTime=ymd_hms(c("2020-05-01 13:30:01.354", "2020-05-01 13:30:01.454", "2020-05-01 13:30:01.612", 
                                        "2020-05-01 13:30:01.663", "2020-05-01 13:30:01.775", "2020-05-01 13:30:02.090", 
                                        "2020-05-01 13:30:02.139", "2020-05-01 13:30:02.190", "2020-05-01 13:30:02.308", 
                                        "2020-05-01 13:30:02.428")),

          Price=c(174.003, 174.003, 174.592, 174.812, 174.742, 174.742, 174.742, 174.743, 174.612, 174.612),
          Volume=c(750, 750, 750, 750, 750, 2000, 750, 2000, 2000, 750))

groupedData <- data %>%
  mutate(Date=lubridate::as_date(DateTime)) %>% 
  group_by(Date, Price) %>% 
  summarise(Volume=sum(Volume)) %>% 
  ungroup()

groupedData

Давать

# A tibble: 6 x 3
  Date       Price Volume
  <date>     <dbl>  <dbl>
1 2020-05-01  174.   1500
2 2020-05-01  175.    750
3 2020-05-01  175.   2750
4 2020-05-01  175.   3500
5 2020-05-01  175.   2000
6 2020-05-01  175.    750
1 голос
/ 29 мая 2020

Как говорит Ронак Шах, вы можете просто сгруппировать по цене, а затем взять совокупную сумму объема. Однако вам нужно быть осторожным, потому что, если вы просто группируете по цене, вы непреднамеренно сгруппируете некоторые более поздние строки с более ранними строками (скажем, если цена повышается, то позже возвращается в то же место). Полагаю, ты этого не хочешь. Поэтому вы должны группировать по соседним строкам с одинаковой ценой. Вы можете сделать это так:

library(dplyr)

df %>% 
  mutate(PriceChange = cumsum(c(TRUE, diff(Price) != 0))) %>%
  group_by(PriceChange) %>%
  mutate(CumSumVolume = cumsum(Volume)) %>% 
  ungroup() %>% 
  select(-PriceChange) %>%
  as.data.frame()

Первые несколько строк вывода будут выглядеть так:

#>                    DateTime   Price Volume      Group CumSumVolume
#> 1   2020-05-01 13:30:01.354 174.003    750 2020-05-01          750
#> 2   2020-05-01 13:30:01.454 174.003    750 2020-05-01         1500
#> 3   2020-05-01 13:30:01.612 174.592    750 2020-05-01          750
#> 4   2020-05-01 13:30:01.663 174.812    750 2020-05-01          750
#> 5   2020-05-01 13:30:01.775 174.742    750 2020-05-01          750
#> 6   2020-05-01 13:30:02.090 174.742   2000 2020-05-01         2750
#> 7   2020-05-01 13:30:02.139 174.742    750 2020-05-01         3500
#> 8   2020-05-01 13:30:02.190 174.743   2000 2020-05-01         2000
#> 9   2020-05-01 13:30:02.308 174.612   2000 2020-05-01         2000
#> 10  2020-05-01 13:30:02.428 174.612    750 2020-05-01         2750
#> 11  2020-05-01 13:30:02.554 174.522   2000 2020-05-01         2000
#> 12  2020-05-01 13:30:02.656 174.552    750 2020-05-01          750
#> 13  2020-05-01 13:30:02.705 174.583   2000 2020-05-01         2000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...