简体   繁体   English

使用dplyr汇总逻辑数据帧

[英]summarise logical dataframe with dplyr

I'm trying to summarise a dataframe using two variables - I basically want to break down variable 1 by variable 2 in order to plot the results in a 100% stacked bar chart. 我试图用两个变量来总结一个数据帧 - 我基本上想要用变量2来分解变量1,以便将结果绘制在100%堆积条形图中。

I have multiple columns of type logical, which can be split between two main categories that will be used to create the breakdown. 我有多个逻辑类型的列,可以分为两个主要类别,用于创建细分。

I have tried to use gather from dplyr to transform the dataframe to longform, however the output is not what I expect. 我曾尝试使用gatherdplyr到数据帧转换为长篇,但输出是不是我所期望的。

topics_by_variable <- function (dataset, variable_1, variable_2) {

  #select variables columns
  variable_1_columns <- dataset[, data.table::`%like%`(names(dataset), variable_1)]
  variable_2_columns <- dataset[, data.table::`%like%`(names(dataset), variable_2)]
  #create new dataframe including only relevant columns
  df <- cbind(variable_1_columns, variable_2_columns)
  #transform df to long form
  new_df <- tidyr::gather(df, variable_2, count, names(variable_2_columns[1]):names(variable_2_columns)[length(names(variable_2_columns))], factor_key=FALSE)

  #count topics
  topic_count <- function (x) {
                  t <- sum(x == TRUE)
  }
  #group by variable 2 and count
  new_df <- new_df %>%
            dplyr::group_by(variable_2) %>%
            dplyr::summarise_at(topic_names, .funs = topic_count)

  #transform new_df to longform
  final_df <- tidyr::gather(new_df, topic, volume, names(variable_1_columns[1]):names(variable_1_columns)[length(names(variable_1_columns))], factor_key=FALSE)
  final_df <- data.frame(final_df)

Here is the dataset I'm using: 这是我正在使用的数据集:

structure(list(topic_su = c("TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), topic_so = c("FALSE", 
"FALSE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "FALSE", "FALSE", "FALSE", "FALSE"), topic_cl = c("FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"
), topic_in = c("FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE"), topic_qu = c("FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), topic_re = c("FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), brands_ne = c("TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"
), brands_st = c("FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE"), brands_co = c("FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"
), brands_seg = c("FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), brands_sen = c("TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", 
"TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE", "TRUE"), brands_ta = c("FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "TRUE"), brands_tc = c("FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", "FALSE", 
"FALSE", "FALSE")), class = "data.frame", row.names = c(NA, -39L
))

The desired output would be the following, however when I use gather the volume figure is the total number of rows and is repeated across all brands. 所需的输出如下,但是当我使用聚集时,体积数字是总行数,并在所有品牌中重复。

variable_2       topic                volume
   <chr>            <chr>              <int>
 1 brands_co     topic_su               10
 2 brands_ne     topic_su               17
 3 brands_seg    topic_su               10 
 4 brands_sen    topic_su               18
 5 brands_st     topic_su                0
 6 brands_ta     topic_su                1
 7 brands_tc     topic_su                0
 8 brands_co     topic_so               22
 9 brands_ne     topic_so               17
10 brands_seg    topic_so               11 
11 brands_sen    topic_so               23
12 brands_st     topic_so                0
13 brands_ta     topic_so                0
14 brands_tc     topic_so                0

Assuming that your dataset is dt you can do something like this: 假设您的数据集是dt您可以执行以下操作:

library(dplyr)

expand.grid(brand = names(dt)[grepl("brands", names(dt))],         
            topic = names(dt)[grepl("topic", names(dt))],
            stringsAsFactors = F) %>%
  rowwise() %>%
  mutate(volume = sum(dt[brand] == "TRUE" & dt[topic] == "TRUE")) %>%
  ungroup()

# # A tibble: 42 x 3
#   brand      topic    volume
#   <chr>      <chr>     <int>
# 1 brands_ne  topic_su     17
# 2 brands_st  topic_su      0
# 3 brands_co  topic_su     10
# 4 brands_seg topic_su     10
# 5 brands_sen topic_su     18
# 6 brands_ta  topic_su      1
# 7 brands_tc  topic_su      0
# 8 brands_ne  topic_so     17
# 9 brands_st  topic_so      0
#10 brands_co  topic_so     22
# # ... with 32 more rows

The process does the following: 该过程执行以下操作:

You get all column names (from original dataset) that match "brands" and "topic" and create all possible combinations between them. 您将获得与“品牌”和“主题”匹配的所有列名称(来自原始数据集),并在它们之间创建所有可能的组合。

For each combination, you get the corresponding columns of your original dataset and count how many times they are both TRUE. 对于每个组合,您将获得原始数据集的相应列,并计算它们都为TRUE的次数。

An alternative could be to use a vectorised function instead of rowwise , which might be faster: 另一种方法是使用矢量化函数而不是行rowwise ,这可能更快:

# vectorised function
GetVolume = function(x,y) sum(dt[x] == "TRUE" & dt[y] == "TRUE")
GetVolume = Vectorize(GetVolume)

expand.grid(brand = names(dt)[grepl("brands", names(dt))],         
            topic = names(dt)[grepl("topic", names(dt))],
            stringsAsFactors = F) %>%
  mutate(volume = GetVolume(brand, topic)) 

Another tidyverse solution: 另一个整体解决方案:

library(tidyverse)

## data    
head(df)
#>   topic_su topic_so topic_cl topic_in topic_qu topic_re brands_ne
#> 1     TRUE    FALSE    FALSE    FALSE    FALSE    FALSE      TRUE
#> 2     TRUE    FALSE    FALSE    FALSE    FALSE    FALSE      TRUE
#> 3     TRUE     TRUE    FALSE    FALSE    FALSE    FALSE      TRUE
#> 4     TRUE     TRUE    FALSE    FALSE    FALSE    FALSE      TRUE
#> 5     TRUE     TRUE    FALSE    FALSE    FALSE    FALSE      TRUE
#> 6     TRUE     TRUE    FALSE    FALSE    FALSE    FALSE      TRUE
#>   brands_st brands_co brands_seg brands_sen brands_ta brands_tc
#> 1     FALSE     FALSE      FALSE       TRUE     FALSE     FALSE
#> 2     FALSE     FALSE      FALSE       TRUE     FALSE     FALSE
#> 3     FALSE     FALSE      FALSE       TRUE     FALSE     FALSE
#> 4     FALSE     FALSE      FALSE       TRUE     FALSE     FALSE
#> 5     FALSE     FALSE      FALSE       TRUE     FALSE     FALSE
#> 6     FALSE     FALSE      FALSE       TRUE     FALSE     FALSE

mutate_all(df, as.logical) %>%
    gather(key = "topic", value = "topic_value", starts_with("topic")) %>%
    gather(key = "variable_2", value = "variable_2_value", -starts_with("topic")) %>%
    group_by(topic, variable_2) %>%
    summarize(volume = sum(topic_value & variable_2_value))
#> # A tibble: 42 x 3
#> # Groups:   topic [6]
#>    topic    variable_2 volume
#>    <chr>    <chr>       <int>
#>  1 topic_cl brands_co      22
#>  2 topic_cl brands_ne      16
#>  3 topic_cl brands_seg     15
#>  4 topic_cl brands_sen     15
#>  5 topic_cl brands_st       0
#>  6 topic_cl brands_ta       1
#>  7 topic_cl brands_tc       0
#>  8 topic_in brands_co      23
#>  9 topic_in brands_ne      16
#> 10 topic_in brands_seg     15
#> # … with 32 more rows

Created on 2019-06-24 by the reprex package (v0.3.0) reprex包创建于2019-06-24(v0.3.0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 dplyr总结逻辑条件 - dplyr summarise logical condition 使用汇总(dplyr)的结果来改变原始数据帧 - Using the result of summarise (dplyr) to mutate the original dataframe R function 中的 dplyr::summarise() 因“参数不是数字或逻辑”错误而失败 - dplyr::summarise() in an R function fails with “argument not numeric or logical” error 用 dplyr 中的汇总创建的平均值减去一个数据帧中的值 - subtract the values in one dataframe by the mean created by summarise in dplyr dplyr summary :按循环中的多个变量分组并将结果添加到同一数据框中 - dplyr summarise : Group by multiple variables in a loop and add results in the same dataframe 如何在 dplyr 和 R 中汇总和子集多级分组 dataframe - How to summarise and subset multi-level grouped dataframe in dplyr and R 使用多个不同的group_by变量(dplyr)来汇总数据帧 - Using multiple different group_by variables (dplyr) to summarise a dataframe dplyr通过将摘要函数应用于另一个数据框来计算新列 - dplyr calculate a new column by applying summarise function on another dataframe dplyr()分组并获取计数-错误消息评估错误:“ summarise_”的适用方法不适用于“逻辑”类的对象 - dplyr() grouping and getting counts - error message Evaluation error: no applicable method for 'summarise_' applied to an object of class “logical” 总结 if 条件中的逻辑语句 - Summarise logical statement in if condition
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM