Транспонировать и суммировать различные значения в R - PullRequest
1 голос
/ 17 июня 2020

ЕСТЬ ли способ транспонировать и суммировать различные значения в R. Например

df
Cola    Order   Quantity    Loc
ABC     1        4         LocA
ABC     1        4         LocB
CSD     4        6         LocA
CDS     3        2         LocB

У нас одинаковые значения для Order и Quantity, но все же нужно взять их сумму.

Ожидается Вывод (транспонирование по количеству)

Cola    Order   Quantity    LocA_Quantity   Loc B_Quantity
ABC      2       8             4                4
CSD      4       6             6
CDS      3       2                              2

Ответы [ 3 ]

0 голосов
/ 17 июня 2020

Это можно сделать как для столбцов "Количество", так и для столбцов "Заказ", а также удалить ненужные столбцы в конце, т.е.

library(tidyverse)

df %>% 
 group_by(Cola) %>% 
 mutate_at(vars(2:3), list(new = sum)) %>% 
 pivot_wider(names_from = Loc, values_from = 2:3)


## A tibble: 3 x 7
## Groups:   Cola [3]
#  Cola  Order_new Quantity_new Order_LocA Order_LocB Quantity_LocA Quantity_LocB
#  <fct>     <int>        <int>      <int>      <int>         <int>         <int>
#1 ABC           2            8          1          1             4             4
#2 CSD           4            6          4         NA             6            NA
#3 CDS           3            2         NA          3            NA             2
0 голосов
/ 17 июня 2020

1) dplyr / tidyr Используя данные, воспроизводимые в примечании в конце, просуммируйте заказы и количество и создайте столбец Quantity_, равный Quantity на Cola. Затем измените форму столбца Quantity_ на широкую.

library(dplyr)
library(tidyr)

df %>%
  group_by(Cola) %>%
  mutate(Quantity_ = Quantity,
    Order = sum(Order), 
    Quantity = sum(Quantity)) %>%
  ungroup %>%
  pivot_wider(names_from = "Loc", values_from = "Quantity_",
    names_prefix = "Quantity_", values_fill = list(Quantity_ = 0))  

давая:

# A tibble: 3 x 5
  Cola  Order Quantity Quantity_LocA Quantity_LocB
  <chr> <int>    <int>         <int>         <int>
1 ABC       2        8             4             4
2 CSD       4        6             6             0
3 CDS       3        2             0             2

2) Базовый R Мы можем сделать то же самое с базовым R используя transform / ave и измените форму следующим образом:

df2 <- transform(df, 
  Quantity_ = Quantity,
  Quantity = ave(Quantity, Cola, FUN = sum),
  Order = ave(Order, Cola, FUN = sum))
wide <- reshape(df2, dir = "wide", idvar = c("Cola", "Quantity", "Order"),
  timevar = "Loc", sep = "")
wide
##   Cola Order Quantity Quantity_LocA Quantity_LocB
## 1  ABC     2        8             4             4
## 3  CSD     4        6             6            NA
## 4  CDS     3        2            NA             2

Note

Lines <- "Cola    Order   Quantity    Loc
ABC     1        4         LocA
ABC     1        4         LocB
CSD     4        6         LocA
CDS     3        2         LocB"
df <- read.table(text = Lines, header = TRUE, as.is = TRUE)
0 голосов
/ 17 июня 2020

Создайте набор данных:

library(tibble)

df = tribble(
  ~Cola,    ~Order,   ~Quantity,  ~Loc,
  'ABC',     1,        4,         'LocA',
  'ABC',     1,        4,         'LocB',
  'CSD',     4,        6,         'LocA',
  'CDS',     3,        2,         'LocB'
)

Создайте сводки:

library(dplyr)

df %>%
  group_by(Cola) %>%
  summarise(
    Order = sum(Order),
    LocA_Quantity = sum(Quantity * if_else(Loc == "LocA", 1, 0)),
    LocB_Quantity = sum(Quantity * if_else(Loc == "LocB", 1, 0)),
    Quantity = sum(Quantity)
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...