Как сгруппировать с оператором if в R? - PullRequest
0 голосов
/ 04 января 2019

У меня есть данные, содержащие четыре переменные (id, количество, вес, дата), и я хочу сделать пакеты с количеством = 6, используя только наблюдения с количеством ниже 6, например: если у меня есть 6 продуктов с количеством 1, каждое, я хочу взамен только 1 продукт из количества 6, где я суммирую (вес [который (qte) <6]) И сделать это для всех элементов таблицы </p>

Я пробовал этот код, но он не работает, кто-нибудь может мне помочь, пожалуйста?

poids = c()
qte =c()
dd = data.frame()
for (i in length(paquet)){
  if(paquet$RealQuantity[i]+paquet$RealQuantity[i+1]==6){
    poids[i] = sum(paquet$RealWeigth)
    qte[i] = sum(paquet$RealQuantity)
    dd = rbind(dd,data.frame(i=i,poids = poids[i],qte =qte[i]))
  }
}

это пример:

A tibble: 232 x 4
   ProductID RealQuantity RealWeigth PickingDate
       <dbl>        <dbl>      <dbl> <date>     
 1         1            5      0.296 2017-12-26 
 2         1            1      0.064 2018-01-05 
 3         1            1      0.061 2018-01-05 
 4         1            5      0.297 2018-01-10 
 5         1            5      0.298 2018-01-13 
 6         1            1      0.058 2018-01-16 
 7         1            3      0.172 2018-01-23 
 8         1            3      0.172 2018-01-23 


the output expected is : 

 ProductID   RealQuantity   RealWeigth PickingDate
       <dbl>        <dbl>      <dbl> <date>     
 1         1            6      0.36  2017-12-26 
 2         1            6      0.358 2018-01-05     
 3         1            6      0.356 2018-01-13 
 4         1            6      0.344 2018-01-23 

1 Ответ

0 голосов
/ 04 января 2019

Это итеративное решение, которое не может гарантировать, что всем назначен пакет из 6 элементов:

df <- structure(list(ProductID = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), RealQuantity = c(5, 1, 1, 5, 5, 1, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3), RealWeigth = c(0.296, 0.064, 0.061, 0.297, 0.298, 0.058, 0.172, 0.172, 0.177, 0.1695, 0.179, 0.18, 0.175, 0.301, 0.181, 0.178, 0.161, 0.178, 0.1775, 0.183), PickingDate = structure(c(17526, 17536, 17536, 17541, 17544, 17547, 17554, 17554, 17554, 17555, 17556, 17556, 17557, 17557, 17557, 17557, 17558, 17561, 17562, 17562), class = "Date")), row.names = c(NA, -20L), class = c("tbl_df", "tbl", "data.frame"))

# for portion of data.frame with RealQuantity < 6:

df$group <- NA
df <- df[order(df$RealQuantity, decreasing=TRUE),]

gi <- 0
groupsize <- 0
while (TRUE) {
  gi <- gi + 1
  # find biggest, non-assigned row:
  i <- min(which(is.na(df$group)))
  if (is.infinite(i)) # nothing found; which would return a zero-length vector. But min(integer(0)) returns Inf.
    break
  groupsize <- df$RealQuantity[i]
  df$group[i] <- gi
  # find next line whos combined quantity might fit within "6":
  while (TRUE) {
    j <- min(which(is.na(df$group) & df$RealQuantity + groupsize <= 6))
    if (is.infinite(j)) # nothing found
      break
    groupsize <- groupsize + df$RealQuantity[j]
    df$group[j] <- gi
    if (groupsize >= 6)
      break
  }

}

library(dplyr)
df %>% group_by(group) %>% summarise_at(vars(RealQuantity, RealWeigth), funs(sum))

или более подробная информация:

df %>% group_by(group) %>% summarise(combined=paste(RealQuantity, collapse=', '), RealQuantity=sum(RealQuantity), RealWeigth=sum(RealWeigth), Firstdate=min(PickingDate))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...