получить количество и сумму в том же столбце в R - PullRequest
3 голосов
/ 14 апреля 2019

У меня есть упомянутый ниже фрейм данных в R.

ID       Date         Type         Value
K-1      2018-01-01   A            4
K-2      2018-01-01   B            7
K-3      2018-01-01   C            12
K-4      2018-01-02   A            6
K-5      2018-01-02   A            4
K-6      2018-01-02   B            15
K-7      2018-01-02   B            10

Я хочу узнать, как преобразовать фрейм данных в приведенный ниже требуемый фрейм данных, где A, B и C должны быть статическими для каждой даты, независимо от того, доступен этот конкретный тип или нет на эту дату .

Кроме того, я хочу посчитать группу ID по дате и Type в интервале <5 (если значение находится в диапазоне от 1 до 4), 5-10 (если значение находится в диапазоне от 5 до 10 ) и >10 (если значение больше 10).

sum столбец должен состоять из итоговой суммы для этой конкретной даты и типа.

Столбец

Count должен состоять из количества групп ID на определенную дату и Type.

Блок <5, 5-10 и >10 всегда должен присутствовать в требуемом выводе, независимо от того, доступно ли значение для этого блока или нет.

Кроме того, как получить сумму конкретной группы ID по их корзине в скобках () с разделенными запятыми двумя десятичными значениями. Шрифт sum в скобках должен быть меньше шрифта count (т. Е. Если шрифт count для <5 bucket равен 12, то шрифт sum в скобках должен быть 10). Кроме того, если счетчик в конкретном сегменте равен 0, то нет необходимости в скобках с (0,00) в качестве значения.

Обязательный DF

Date           Count      <5      5-10       >10      sum
2018-01-01      3         1 (4)    1 (7)      1 (12)   23
A               1         1 (4)    0          0        4
B               1         0        1 (7)      0        7
C               1         0        0          1 (12)   12
2018-01-02      4         1 (4)    2 (16)     1 (15)   35
A               2         1 (4)    1 (6)      0        10
B               2         0        1 (10)     1 (15)   25
C               0         0        0          0        0

Код, который я использую (из SO):

library(tidyverse)

dat2 <- dat %>%
  mutate(Result = case_when(
    Value < 5                        ~"<5",
    Value >= 5 & Value <= 10         ~"5-10",
    Value > 10                       ~">10"
  )) %>%
  group_by(Date, Type, Result) %>%
  summarize(sum = sum(Value)) %>%
  mutate(Flag = 1L) %>%
  spread(Result, Flag, fill = 0L) %>%
  group_by(Date, Type) %>%
  summarize_all(list(~sum(.))) %>%
  ungroup() %>%
  complete(Date, Type)

dat2[is.na(dat2)] <- 0

dat3 <- dat2 %>% mutate(Count = rowSums(select(., -Date, -Type, -sum)))

dat4 <- dat3 %>%
  group_by(Date) %>%
  summarize_at(vars(-Type), list(~sum(.))) 

dat_final <- map2_dfr(split(dat4, f = dat4$Date),
                      split(dat3, f = dat3$Date),
                      ~bind_rows(.x %>% rename(Type = Date), 
                                 .y %>% select(-Date)))

dat_final2 <- dat_final %>%
  select(Date = Type, Count, `<5`, `5-10`, `>10`, sum)
dat_final2

1 Ответ

2 голосов
/ 14 апреля 2019

Пакет таблиц хорош для компактного описания такого вывода. Сначала создайте функции, которые вычисляют статистику, показанную в столбцах. Затем используйте указанную формулу tabular. LHS - это строки, а RHS - это столбцы. + означает объединение переменных, описанных по обе стороны от +.

Вывод sprintf может быть изменен, например, путем изменения строки формата. Смотри ?sprintf.

Латекс

Также, если tab является выводом команды tabular, тогда latex(tab) создаст версию для латекса, и вы можете изменить ее, вставив команды для латекса. Например, "%d \\tiny{(%d)}" в качестве строки формата sprintf уменьшит часть в скобках в выводе латекса.

HTML

Если вы хотите выводить html, тогда с tab, как только что определено, тогда html(tab) создает HTML-версию, которая может быть изменена в дальнейшем с помощью соответствующих HTML-тегов. Например, "%d <small>(%d)</small>" в качестве строки формата sprintf уменьшит часть в скобках в выводе html.

ввод

Мы предоставляем ввод dat в воспроизводимой форме в примечании в конце. В следующий раз убедитесь, что ввод предоставлен в воспроизводимой форме.

код

Это в основном воспроизводит вывод, показанный в вопросе, и намного более компактен, чем код там.

library(tables)

outstring <- function(x) if (length(x)) sprintf("%d (%d)", length(x), sum(x)) else 0
`<5` <- function(x) outstring(x[x < 5])
`5-10` <- function(x) outstring(x[x >= 5 & x <= 10])
`>10` <- function(x) outstring(x[x > 10])

tab <- 
  tabular(Date * (1 + Type) ~ (n=1) + Value * (`<5` + `5-10` + `>10` + sum), data = dat)

дает:

                       Value                  
 Date                n <5    5-10   >10    sum
 2018-01-01      All 3 1 (4) 1 (7)  1 (12) 23 
            Type A   1 1 (4) 0      0       4 
                 B   1 0     1 (7)  0       7 
                 C   1 0     0      1 (12) 12 
 2018-01-02      All 4 1 (4) 2 (16) 1 (15) 35 
            Type A   2 1 (4) 1 (6)  0      10 
                 B   2 0     1 (10) 1 (15) 25 
                 C   0 0     0      0       0 

Примечание

dat <- 
structure(list(ID = structure(1:7, .Label = c("K-1", "K-2", "K-3", 
"K-4", "K-5", "K-6", "K-7"), class = "factor"), Date = structure(c(1L, 
1L, 1L, 2L, 2L, 2L, 2L), .Label = c("2018-01-01", "2018-01-02"
), class = "factor"), Type = structure(c(1L, 2L, 3L, 1L, 1L, 
2L, 2L), .Label = c("A", "B", "C"), class = "factor"), Value = c(4L, 
7L, 12L, 6L, 4L, 15L, 10L)), class = "data.frame", row.names = c(NA, 
-7L))

Обновление

Класс tabular имеет метод as.matrix, и мы можем выполнить простые манипуляции с ним для получения следующего вывода:

m <- as.matrix(tab)
m2 <- cbind(paste0(m[, 1], sub("All", "", m[, 3])), m[, -(1:3)])[-1, ]
setNames(as.data.frame(m2[-1, ]), m2[1, ])

дает:

        Date n    <5   5-10    >10 sum
1 2018-01-01 3 1 (4)  1 (7) 1 (12)  23
2          A 1 1 (4)      0      0   4
3          B 1     0  1 (7)      0   7
4          C 1     0      0 1 (12)  12
5 2018-01-02 4 1 (4) 2 (16) 1 (15)  35
6          A 2 1 (4)  1 (6)      0  10
7          B 2     0 1 (10) 1 (15)  25
8          C 0     0      0      0   0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...