Как суммировать переменную по группам

#r #dplyr #tidyverse #aggregation

#r #dplyr #tidyverse #агрегирование

Вопрос:

Итак, у меня есть образец данных

 structure(list(Conversation = c(1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 
2L, 2L, 3L, 3L), ID.Number = c("ID 11", "ID 11", "ID 11", "ID 11", 
"ID 11", "ID 11", "ID 14", "ID 14", "ID 14", "ID 14", "ID 14", 
"ID 14"), Swear.word = c(0L, 2L, 4L, 3L, 0L, 0L, 1L, 0L, 3L, 
1L, 0L, 4L)), class = "data.frame", row.names = c(NA, -12L))
  

И я пытаюсь получить результат, который выглядит так

 structure(list(IDNumber = c(11L, 14L), Convo1 = 2:1, Convo2 = c(7L, 4L), Convo3 = c(0L, 4L)), class = "data.frame", row.names = c(NA, -2L))
  

Итак, по сути, я пытаюсь увидеть использование нецензурных слов (сумма словоупотребления) по типу разговора (convo #) для каждого участника.

Как я могу это сделать, используя R?

Спасибо!

Ответ №1:

Попробуйте этот tidyverse подход. Я использовал общие данные как A . Вы можете использовать pivot_wider() в одном коде, чтобы получить желаемый результат. Здесь код:

 library(tidyverse)
#Code
New <- A %>% mutate(Conversation=paste0('Conv.',Conversation)) %>%
  pivot_wider(names_from = Conversation,values_from=Swear.word,values_fn = sum)
  

Вывод:

 # A tibble: 2 x 4
  ID.Number Conv.1 Conv.2 Conv.3
  <chr>      <int>  <int>  <int>
1 ID 11          2      7      0
2 ID 14          1      4      4
  

И оптимальный вариант кода может быть (большое спасибо и благодарность @starja):

 #Code 2
Newdf <- A %>% pivot_wider(names_from = Conversation,
                  values_from=Swear.word,
                  values_fn = sum,names_prefix='Conv.')
  

Вывод:

 # A tibble: 2 x 4
  ID.Number Conv.1 Conv.2 Conv.3
  <chr>      <int>  <int>  <int>
1 ID 11          2      7      0
2 ID 14          1      4      4
  

Комментарии:

1. Разумное использование values_fn ! Чтобы использовать только pivot_wider , вы могли бы использовать names_prefix

2. @starja Отличный совет, позвольте мне добавить эту часть с благодарностью к вам!

Ответ №2:

Это должно сработать

 library(tidverse)


df <- x %>%
    group_by(ID.Number, Conversation) %>%
    summarize(
        total = sum(Swear.word, na.rm = TRUE)
    ) %>%
    spread(Conversation, total) %>%
    magrittr::set_colnames(c("IDNumber","Convo1","Convo2", "Convo3"))
df
  

Ответ №3:

Вот подход с dplyr , tidyr и stringr :

 library(dplyr)
library(tidyr)
library(stringr)

data %>% 
  mutate(ID.Number = as.integer(str_extract(ID.Number, "\d "))) %>% 
  group_by(ID.Number, Conversation) %>% 
  summarise(count = sum(Swear.word)) %>% 
  pivot_wider(
    id_cols = ID.Number,
    names_from = Conversation,
    values_from = count,
    names_prefix = "Convo"
  ) %>% 
  rename(IDNumber = ID.Number)
# A tibble: 2 x 4
# Groups:   IDNumber [2]
  IDNumber Convo1 Convo2 Convo3
     <int>  <int>  <int>  <int>
1       11      2      7      0
2       14      1      4      4
  

Ответ №4:

Мы можем использовать xtabs из base R

 xtabs(Swear.word ~ ID.Number   Conversation, df1)
#        Conversation
#ID.Number 1 2 3
#    ID 11 2 7 0
#    ID 14 1 4 4
  

Или используя dcast из data.table

 library(data.table)
dcast(setDT(df1), ID.Number ~ paste0('Conv.', Conversation), 
     value.var = 'Swear.word', sum)
#   ID.Number Conv.1 Conv.2 Conv.3
#1:     ID 11      2      7      0
#2:     ID 14      1      4      4