Столбец суммы в DataFrame в R

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

Ниже приведен воспроизводимый пример:

df <- data.frame("6Jun06" = c(4, 5, 9),
    "13Jun06" = c(4, 5, 9),
    "20Jun06" = c(4, 5, 9),
    "03Jul16" = c(1, 2, 3),
    "09Jul16" = c(1, 2, 3),
    "01Aug16" = c(1, 2, 5))

Так что в этом случае мне нужно было бы иметь три столбца (после июня, июля и августа).

  X6.Jun.06 X13.Jun.06 X20.Jun.06 Jun.Sum X03.Jul.16 X09.Jul.16 Jul.Sum X01.Aug.16 Aug.Sum
1         4          4          4     Sum          1          1     Sum          1     Sum
2         5          5          5     Sum          2          2     Sum          2     Sum
3         9          9          9     Sum          3          3     Sum          5     Sum

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


person A.J    schedule 27.06.2016    source источник


Ответы (3)


Если вы новичок в R, хорошим началом будет знакомство с экосистемой dplyr (а также с другими пакетами Хэдли Уикхема).

library(dplyr)
library(tidyr)

df %>%
   mutate(id = 1:nrow(df)) %>%
   gather(date, value, -id) %>%
   mutate(Month = month.abb[apply(sapply(month.abb, function(mon) {grepl(mon, .$date)}), 1, which)]) %>%
   group_by(id, Month) %>%
   summarize(sum = sum(value)) %>%
   spread(Month, sum) %>%
   left_join(mutate(df, id = 1:nrow(df)), .) %>%
   select(-id)
person toni057    schedule 27.06.2016
comment
Спасибо за предложение обновить пакеты. И ваш ответ, и ответ Сотоса отлично сработали. - person A.J; 28.06.2016

Вы немного усложняете себе жизнь, используя имена переменных, которые начинаются с цифры, так как R будет вставлять перед ними X. Однако есть один способ получить желаемую сумму.

#1. Use the package `reshape2`:

    library(reshape2)
    dfm <- melt(df)

#2.  Get rid of the X in the dates, then convert to a date using the package `lubridate` and extract the month:

    library(lubridate) 
    dfm$Date <- dmy(substring(dfm$variable, 2))
    dfm$Month <- month(dfm$Date)

#3. Then calculate the sum for each month using the `dplyr` package:

    library(dplyr)
    dfm %>% group_by(Month) %>% summarise(sum(value))
person David_B    schedule 27.06.2016
comment
Я думаю, вам нужно перепроверить свое решение по вопросу OP (и ожидаемому результату) - person Sotos; 27.06.2016

Вот один из способов добавления новых столбцов в конец фрейма данных:

cbind(df, sapply(unique(gsub('\\d+', '', names(df))), function(i)
                          rowSums(df[grepl(i, sub('\\d+', '', names(df)))])))

#  6Jun06 13Jun06 20Jun06 03Jul16 09Jul16 01Aug16 Jun Jul Aug
#1      4       4       4       1       1       1  12   2   1
#2      5       5       5       2       2       2  15   4   2
#3      9       9       9       3       3       5  27   6   5
person Sotos    schedule 27.06.2016