我正在尝试使用两个变量来总结一个数据帧-我基本上想将变量1分解为变量2,以便将结果绘制在100%堆叠的条形图中。
我有多个逻辑类型的列,可以将其分为两个主要类别,以用于创建细分。
我尝试使用gather
中的dplyr
将数据帧转换为长格式,但是输出不是我期望的。
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)
这是我正在使用的数据集:
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
))
所需的输出将是以下内容,但是当我使用collect时,体积图是行的总数,并且在所有品牌中都重复出现。
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
答案 0 :(得分:3)
假设您的数据集为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
该过程执行以下操作:
您将从原始数据集中获得与“品牌”和“主题”匹配的所有列名,并在它们之间创建所有可能的组合。
对于每种组合,您都会获得原始数据集的相应列,并计算它们都为TRUE的次数。
另一种选择是使用向量化函数代替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))
答案 1 :(得分:0)
另一个tidyverse解决方案:
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
由reprex package(v0.3.0)于2019-06-24创建