使用R ggplot对比不同平台的相似分类数据列频率
解决方案:按平台分组的Context分类频率对比柱状图
方法一:转成整洁数据格式(推荐)
你之前用mutate合并列时NA覆盖有效数据,核心原因是数据集是宽格式(一个平台对应一列),而ggplot绘图需要的是长格式(每行对应一个有效数据点)。用tidyr::pivot_longer可以直接解决这个问题,自动过滤NA值,不用写复杂的if/else逻辑。
代码示例
假设你的数据集名为df:
# 加载必备包 library(tidyverse) # 把宽格式转成长格式,自动去掉NA行 df_long <- df %>% pivot_longer( cols = ends_with("_context"), # 选中所有带_context后缀的列 names_to = "source_platform", # 存储原列名的新列 values_to = "context", # 存储Context内容的新列 values_drop_na = TRUE # 直接过滤掉NA的行 ) %>% # 从原列名里提取平台名称(比如twitter_context → twitter) mutate(source_platform = str_remove(source_platform, "_context")) # 统计每个分组的频率 df_freq <- df_long %>% count(platform, source_platform, context, name = "frequency") # 绘制分组对比柱状图 ggplot(df_freq, aes(x = context, y = frequency, fill = source_platform)) + geom_col(position = "dodge") + # 并列显示不同平台的柱子 facet_wrap(~platform) + # 按原数据集的platform列拆分子图 theme(axis.text.x = element_text(angle = 45, hjust = 1)) + # 旋转x轴标签避免重叠 labs(title = "各平台Context分类频率对比", x = "Context类型", y = "出现频率", fill = "数据来源平台")
这种方法的优势是数据格式更规范,后续修改或扩展分析都更方便,且能直接生成跨平台的对比图。
方法二:绘制独立子图后整合
如果不想转换数据格式,也可以分别绘制三个平台的Context频率图,再用patchwork包拼接在一起。
代码示例
library(ggplot2) library(patchwork) # 绘制Twitter的频率图 p_twitter <- df %>% filter(!is.na(twitter_context)) %>% count(twitter_context, name = "frequency") %>% ggplot(aes(x = twitter_context, y = frequency)) + geom_col(fill = "#1DA1F2") + labs(title = "Twitter Context频率", x = "Context", y = "频率") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 绘制Facebook的频率图 p_facebook <- df %>% filter(!is.na(facebook_context)) %>% count(facebook_context, name = "frequency") %>% ggplot(aes(x = facebook_context, y = frequency)) + geom_col(fill = "#4267B2") + labs(title = "Facebook Context频率", x = "Context", y = "频率") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 绘制Instagram的频率图 p_insta <- df %>% filter(!is.na(insta_context)) %>% count(insta_context, name = "frequency") %>% ggplot(aes(x = insta_context, y = frequency)) + geom_col(fill = "#E4405F") + labs(title = "Instagram Context频率", x = "Context", y = "频率") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 拼接三个子图(1行3列布局) p_twitter + p_facebook + p_insta + plot_layout(ncol = 3)
这种方法适合需要单独展示每个平台数据的场景,但跨平台对比的直观性不如方法一。
补充:如果非要用mutate合并列
如果坚持要用mutate+条件判断,前提是platform列的取值和_context列的前缀完全对应(比如platform是"twitter"时,twitter_context有值),可以这么写:
df <- df %>% mutate(context = case_when( platform == "twitter" ~ twitter_context, platform == "facebook" ~ facebook_context, platform == "instagram" ~ insta_context, TRUE ~ NA_character_ ))
但这种方法灵活性差,一旦平台名称或列名变动就会出错,不如pivot_longer通用。
内容的提问来源于stack exchange,提问作者urcho
相关产品推荐
相关产品推荐

