Как получить последние N строк каждой группы в dplyr с отсутствующими строками как 0? - PullRequest
0 голосов
/ 07 мая 2020

У меня есть фрейм данных с идентификатором столбца, категорией, меткой времени, количеством, ценой. Я хочу сгруппировать данные по идентификатору, категории, а затем получить последние 3 значения количества, цены, а затем развернуть таблицу.

library(dplyr)
dummy <- data.frame("ID" = c(1,1,2,2,3),
                    "category"=c("A","A", "B", "A", "C"),
                    "timestamp"=as.Date(c("2020-04-05", "2020-04-10", "2020-03-01", "2020-01-01", "2020-01-10")),
                    "Quantity"=c(1,5,6,7,4),
                    "price"=c(10.2, 45.6, 70.3, 23.4, 10))
> dummy
  ID category  timestamp Quantity price
1  1        A 2020-04-05        1  10.2
2  1        A 2020-04-10        5  45.6
3  2        B 2020-03-01        6  70.3
4  2        A 2020-01-01        7  23.4
5  3        C 2020-01-10        4  10.0

Я хочу выбрать последние 3 строки каждой категории клиентов. если только одна или 2 строки proe snet, тогда заполните отсутствующие строки 0.

dummy2 <- data.frame("ID" = c(1,2,2,3),"category" = c("A","B", "A", "C"),
                     "Quantity1" = c(0,0,0,0),"Quantity2" = c(1,0,0,0),"Quantity3" = c(5,6,7,4),
                     "price1" = c(0,0,0,0),"price2" = c(10.2,0,0,0),"price3" = c(45.6, 70.3, 23.4, 10.0))

> dummy2
  ID category Quantity1 Quantity2 Quantity3 price1 price2 price3
1  1        A         0         1         5      0   10.2   45.6
2  2        B         0         0         6      0    0.0   70.3
3  2        A         0         0         7      0    0.0   23.4
4  3        C         0         0         4      0    0.0   10.0

здесь количество1, количество2, количество3 представляет (последние-2, последние-1, последние) значения строк для каждой категории IDx . Я попробовал dummy %>% group_by(ID, category) %>% dplyr::top_n(-3, wt = timestamp) %>% select(Quantity, price), после этого не знаю, что делать. предложите решение

Ответы [ 2 ]

0 голосов
/ 07 мая 2020

в примере лучше иметь группу с более чем 3 строками.

Я создаю фиктивную группу из 5 строк.

library(data.table)
dummy <- data.frame("ID" = c(1,1,2,2,3),
                    "category"=c("A","A", "B", "A", "C"),
                    "timestamp"=as.Date(c("2020-04-05", "2020-04-10", "2020-03-01", "2020-01-01", "2020-01-10")),
                    "Quantity"=c(1,5,6,7,4),
                    "price"=c(10.2, 45.6, 70.3, 23.4, 10))


dummy2 <- data.frame("ID" = c(4,4,4,4,4),
                    "category"=c("A","A", "A", "A", "A"),
                    "timestamp"=as.Date(c("2020-04-05", "2020-04-10", "2020-03-01", "2020-01-01", "2020-01-10")),
                    "Quantity"=c(1,5,6,7,4),
                    "price"=c(10.2, 45.6, 70.3, 23.4, 10))


dt <- rbindlist(list(dummy,dummy2))
setorder(dt,ID,category,-timestamp)[,grp:=paste0(ID,category)]

result <- dcast(dt[dt[,head(.I,3),by=.(grp)]$V1],ID+category~4-rowid(grp),value.var = c("Quantity","price"))

#replace NA as 0
# looks like you really care about performance so i am going to use set
for (j in seq_len(ncol(result))){
  set(result,which(is.na(result[[j]])),j,0)
}

result
#>    ID category Quantity_1 Quantity_2 Quantity_3 price_1 price_2 price_3
#> 1:  1        A          0          1          5     0.0    10.2    45.6
#> 2:  2        A          0          0          7     0.0     0.0    23.4
#> 3:  2        B          0          0          6     0.0     0.0    70.3
#> 4:  3        C          0          0          4     0.0     0.0    10.0
#> 5:  4        A          6          1          5    70.3    10.2    45.6

Создано 2020-05- 07 с помощью пакета REPEX (v0.3.0)

0 голосов
/ 07 мая 2020

Вот способ:

library(dplyr)
library(tidyr)

dummy %>%
  group_by(ID, category) %>%
  #Get top 3 timestamp values
  top_n(3, timestamp) %>%
  select(-timestamp) %>%
  mutate(row = rev(3 - row_number() + 1)) %>%
  complete(row = 1:3, fill = list(Quantity = 0, price = 0)) %>%
  pivot_wider(names_from = row, values_from = c(Quantity, price))


#     ID category Quantity_1 Quantity_2 Quantity_3 price_1 price_2 price_3
#  <dbl> <chr>         <dbl>      <dbl>      <dbl>   <dbl>   <dbl>   <dbl>
#1     1 A                 0          1          5       0    10.2    45.6
#2     2 A                 0          0          7       0     0      23.4
#3     2 B                 0          0          6       0     0      70.3
#4     3 C                 0          0          4       0     0      10  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...