Каков наилучший способ подсчета значений в столбцах для создания сводной таблицы? - PullRequest
0 голосов
/ 08 февраля 2020

У меня есть tbl_df, в котором есть несколько столбцов с несколькими значениями в них. Я ищу использовать значения в столбцах, чтобы создать несколько столбцов. После этого я собираюсь подвести итог колонки.

Один способ, которым я могу go об этом, - создать несколько ifelse в пределах mutate, но это кажется неэффективным. Есть ли лучший способ go по этому поводу? Я думаю, что, вероятно, существует решение на основе dplyr и / или tidyr.

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

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

df <- tibble::tribble(
  ~type,      ~bb_type,           ~description,
  "B",            NA,                 "ball",
  "S",            NA,                 "foul",
  "X",  "line_drive", "hit_into_play_no_out",
  "S",            NA,      "swinging_strike",
  "S",            NA,                 "foul",
  "X", "ground_ball",        "hit_into_play",
  "S",            NA,      "swinging_strike",
  "X",    "fly_ball",  "hit_into_play_score",
  "B",            NA,                 "ball",
  "S",            NA,                 "foul"
)


df <- df %>% 
  mutate(ground_ball = ifelse(bb_type == "ground_ball", 1, 0),
         fly_ball = if_else(bb_type == "fly_ball", 1, 0),
         X = if_else(type == "X", 1, 0),
# not sure if this is the based way to go about counting columns that start with swinging to sum later
         swinging_strike = grepl("^swinging", description))

df
#> # A tibble: 10 x 7
#>    type  bb_type    description       ground_ball fly_ball     X swinging_strike
#>    <chr> <chr>      <chr>                   <dbl>    <dbl> <dbl> <lgl>          
#>  1 B     <NA>       ball                       NA       NA     0 FALSE          
#>  2 S     <NA>       foul                       NA       NA     0 FALSE          
#>  3 X     line_drive hit_into_play_no…           0        0     1 FALSE          
#>  4 S     <NA>       swinging_strike            NA       NA     0 TRUE           
#>  5 S     <NA>       foul                       NA       NA     0 FALSE          
#>  6 X     ground_ba… hit_into_play               1        0     1 FALSE          
#>  7 S     <NA>       swinging_strike            NA       NA     0 TRUE           
#>  8 X     fly_ball   hit_into_play_sc…           0        1     1 FALSE          
#>  9 B     <NA>       ball                       NA       NA     0 FALSE          
#> 10 S     <NA>       foul                       NA       NA     0 FALSE

summary_df <- df %>% 
  summarize(n = n(),
            fly_ball = sum(fly_ball, na.rm = TRUE),
            ground_ball = sum(ground_ball, na.rm = TRUE))

summary_df
#> # A tibble: 1 x 3
#>       n fly_ball ground_ball
#>   <int>    <dbl>       <dbl>
#> 1    10        1           1

Итак, я хочу сделать следующее:

  1. Создать новые столбцы для всех значений в bb_type и type, которые их подсчитывают
  2. Создать новый столбец, который подсчитывает количество значений, которые начинаются с колебания в столбце описания. Я хотел бы видеть пример, который выбирает другую текстовую строку из этого столбца и создает новый столбец с количеством в качестве дополнительного примера. Ex. ball
  3. Как бы я выбрал собственное имя, делая то, что я хочу достичь в 1 и 2? Должен ли я просто использовать dplyr::rename по факту?

Ответы [ 3 ]

2 голосов
/ 08 февраля 2020

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

addmargins(table(df$bb_type, useNA = 'always'), 1)
#   fly_ball ground_ball  line_drive        <NA>         Sum 
#          1           1           1           7          10 
2 голосов
/ 08 февраля 2020

Похоже, что это запрос на табулирование с последующим подсчетом записей в этой табуляции

tb_df <- table(df$bb_type, useNA="always") 

c(Sum=sum(tb_df), tb_df)
        Sum    fly_ball ground_ball  line_drive        <NA> 
         10           1           1           1           7 

Если вы хотите использовать его в качестве кадра данных, вы сначала превратите его в именованный список:

data.frame( as.list(  c(Sum=sum(tb_df), tb_df) ) )
  Sum fly_ball ground_ball line_drive NA.
1  10        1           1          1   7

Если вы хотите, чтобы это было сделано для всех столбцов, то сначала создайте функцию, которая обрабатывает один столбец, и добавьте ее в tbl_df:

tally_col <- function(x){ tb <- table(x, useNA="always") 
 tal <- c(Sum=sum(tb), tb); data.frame( as.list(tal)) }

lapply(df, tally_col)
# ---output---
$type
  Sum B S X NA.
1  10 2 5 3   0

$bb_type
  Sum fly_ball ground_ball line_drive NA.
1  10        1           1          1   7

$description
  Sum ball foul hit_into_play hit_into_play_no_out hit_into_play_score swinging_strike NA.
1  10    2    3             1                    1                   1               2   0
1 голос
/ 08 февраля 2020

Используя dplyr и tidyr, вы можете сделать что-то подобное. Во-первых, вы можете сгруппировать по переменной "bb_type", указав .drop = FALSE, в порядке dplyr сохранить NA значения. Затем вы можете посчитать их и получить сумму всех подсчитанных значений и, наконец, использовать pivot_wider, чтобы получить данные, отображаемые в нужной вам ориентации:

library(dplyr)
library(tidyr)
df %>% group_by(bb_type, .drop = FALSE) %>%
  count() %>% 
  ungroup() %>% mutate(Sum = sum(n)) %>% 
  pivot_wider(.,names_from = bb_type,values_from = n) 

# A tibble: 1 x 5
    Sum fly_ball ground_ball line_drive  `NA`
  <int>    <int>       <int>      <int> <int>
1    10        1           1          1     7

Это то, что вы ищете

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...