Суммировать?Подсчет вхождений в столбце на основе другого столбца - PullRequest
0 голосов
/ 01 марта 2019

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

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

library(dplyr)

set.seed(1)
df <- tibble("name" = c(rep("dinah",2),rep("lucy",4),rep("sora",9)),
             "meal" = c(rep(c("chicken","beef","fish"),5)),
             "date" = seq(as.Date("1999/1/1"),as.Date("2000/1/1"),25),
             "num.wins" = sample(0:30)[1:15])

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

df
# A tibble: 15 x 4
   name  meal    date       num.wins
   <chr> <chr>   <date>        <int>
 1 dinah chicken 1999-01-01        8
 2 dinah beef    1999-01-26       11
 3 lucy  fish    1999-02-20       16
 4 lucy  chicken 1999-03-17       25
 5 lucy  beef    1999-04-11        5
 6 lucy  fish    1999-05-06       23
 7 sora  chicken 1999-05-31       27
 8 sora  beef    1999-06-25       15
 9 sora  fish    1999-07-20       14
10 sora  chicken 1999-08-14        1
11 sora  beef    1999-09-08        4
12 sora  fish    1999-10-03        3
13 sora  chicken 1999-10-28       13
14 sora  beef    1999-11-22        6
15 sora  fish    1999-12-17       18

Я продвинулся в других вычислениях, которые меня интересуют, ниже:

df %>% 
  group_by(name) %>% 
  summarise(count=n(),
            medianDate=median(date),
            life=(max(date)-min(date)),
            wins=sum(num.wins))

# A tibble: 3 x 5
  name  count medianDate life      wins
  <chr> <int> <date>     <time>   <int>
1 dinah     2 1999-01-13  25 days    19
2 lucy      4 1999-03-29  75 days    69
3 sora      9 1999-09-08 200 days   101

Моя цель - добавить дополнительный столбец для каждого типа пищи и получить суммуслучаев появления этой еды в каждом ряду, например:

  name  count medianDate life      wins  chicken  beef  fish
1 dinah     2 1999-01-13  25 days    19        1     1     0
2 lucy      4 1999-03-29  75 days    69        1     1     2
3 sora      9 1999-09-08 200 days   101        3     3     3

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

Один из вариантов - использовать table внутри summarise в качестве столбца list, unnest, а затем spread в «широком» формате

library(tidyverse)
df %>% 
  group_by(name) %>%
  summarise(count=n(),
             medianDate=median(date),
             life=(max(date)-min(date)),
             wins=sum(num.wins),
             n = list(enframe(table(meal))) ) %>%
  unnest %>%
  spread(name1, value, fill = 0)
# A tibble: 3 x 8
#  name  count medianDate life      wins  beef chicken  fish
#  <chr> <int> <date>     <time>   <int> <dbl>   <dbl> <dbl>
#1 dinah     2 1999-01-13  25 days    19     1       1     0
#2 lucy      4 1999-03-29  75 days    69     1       1     2
#3 sora      9 1999-09-08 200 days   101     3       3     3
0 голосов
/ 01 марта 2019

Хотя старше и, возможно, на пути устаревания, reshape2::dcast делает это красиво:

reshape2::dcast(df, name ~ meal)
#    name beef chicken fish
# 1 dinah    1       1    0
# 2  lucy    1       1    2
# 3  sora    3       3    3

Вы можете понимать формулу как rows ~ columns.По умолчанию он агрегирует значения в столбцах с помощью функции length, которая дает именно то, что вы хотите, количество каждого.

Это может быть легко присоединено к вашим сводным данным:

df %>% 
  group_by(name) %>% 
  summarise(count=n(),
            medianDate=median(date),
            life=(max(date)-min(date)),
            wins=sum(num.wins)) %>%
  left_join(reshape2::dcast(df, name ~ meal))
# # A tibble: 3 x 8
#   name  count medianDate life      wins  beef chicken  fish
#   <chr> <int> <date>     <time>   <int> <int>   <int> <int>
# 1 dinah     2 1999-01-13  25 days    19     1       1     0
# 2 lucy      4 1999-03-29  75 days    69     1       1     2
# 3 sora      9 1999-09-08 200 days   101     3       3     3
0 голосов
/ 01 марта 2019

Я не совсем уверен, почему я получаю причудливое форматирование для life, но я думаю, что это зависит от вашего количества блюд.

df %>% 
  group_by(name) %>% 
  summarise(count=n(),
            medianDate=median(date),
            life=(max(date)-min(date)),
            wins=sum(num.wins),
            chicken = sum(meal == "chicken"),
            beef = sum(meal == "beef"),
            fish = sum(meal == "fish"))

# A tibble: 3 x 8
  name  count medianDate life        wins chicken  beef  fish
  <chr> <int> <date>     <time>     <int>   <int> <int> <int>
1 dinah     2 1999-01-13 " 25 days"    19       1     1     0
2 lucy      4 1999-03-29 " 75 days"    69       1     1     2
3 sora      9 1999-09-08 200 days     101       3     3     3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...