【问题标题】:What is the best way to count values within columns to create a summary table?对列中的值进行计数以创建汇总表的最佳方法是什么?
【发布时间】:2020-02-08 17:46:00
【问题描述】:

我有一个tbl_df,它有几个列,其中包含多个值。我希望使用列中的值来创建几列。在那之后,我正在总结这些专栏。

我可以解决的一种方法是在mutate 中创建多个ifelse,但这似乎效率低下。有没有更好的方法来解决这个问题?我在想可能有一个基于dplyr 和/或tidyr 的解决方案。

下面是我想要做的示例。这只是数据和列的样本。它不包含我要创建的所有列。汇总表将包含一些基于 summean 的列。

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_typetype 中计算它们的所有值创建新列
  2. 创建一个新列,计算描述列中以摆动开头的值的数量。我希望看到一个示例,该示例从该列中选择另一个文本字符串并创建一个带有计数的新列作为附加示例。前任。球
  3. 在做我希望在 1 和 2 中实现的目标时,我将如何选择自己的名字?事后我是否必须简单地使用dplyr::rename

【问题讨论】:

    标签: r dplyr tidyr tabulate


    【解决方案1】:

    我们可以使用tableaddmargins 来自base R

    addmargins(table(df$bb_type, useNA = 'always'), 1)
    #   fly_ball ground_ball  line_drive        <NA>         Sum 
    #          1           1           1           7          10 
    

    【讨论】:

    • @Jazzmatazz 你需要lapply(df, function(x) addmargins(table(x, useNA = 'always'), 1))
    【解决方案2】:

    这似乎是一个制表请求,随后对该制表中的条目进行计数

    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
    

    【讨论】:

      【解决方案3】:

      使用dplyrtidyr 你可以做这样的事情。首先,您可以通过指定.drop = FALSE 按“bb_type”变量分组,以便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
      

      这是你要找的吗?

      【讨论】:

      • 要统计“类型”和“描述”变量的值个数吗?
      • 对于类型,我想计算值。我怎么能这样做,同时也更改创建的列名而无需重命名?为了描述,我只想计算和创造特定的价值,比如挥杆和犯规。
      • @Jazzmatazz 我认为您正在添加尚未模糊描述的要求。如果您希望“描述”比它的值更简洁地概括,那么您需要为该操作提供特定规则。
      • 抱歉,我无法理解您要查找的内容。您能否编辑您的问题以提供您的预期输出(包括描述和类型列的输出)?
      • @Jazzmatazz 我不明白您的问题如何没有被已经提供的内容回答。如果您可以根据您的数据示例提供所需的最终输出,那将会很有帮助。
      猜你喜欢
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      相关资源
      最近更新 更多