DataFrame中因子配对及其逆序对的合并频次计算需求
解决因子配对频次合并统计的问题
看起来你想要的是不区分因子顺序的配对统计——也就是把(A,B)和(B,A)当成同一个配对,(C,D)和(D,C)也合并统计,对吧?原来的plyr::count()会严格区分两列的顺序,所以我们需要先对每一行的两个因子进行排序,让相同的无序配对变成统一的有序格式,再统计频次。
步骤1:准备示例数据
先还原你的示例数据框方便测试:
df <- data.frame( A1 = c("A", "D", "B", "D", "D", "A", "B", "C"), A2 = c("A", "C", "A", "C", "C", "B", "A", "D"), stringsAsFactors = FALSE )
步骤2:统一配对顺序
对每一行的A1和A2元素进行排序,这样不管原来的顺序是A-B还是B-A,都会变成A-B的格式:
# 对每行的两个因子排序,转置后转为数据框 sorted_pairs <- t(apply(df[, c("A1", "A2")], 1, sort)) sorted_df <- as.data.frame(sorted_pairs, stringsAsFactors = FALSE) # 重新命名列名保持一致 colnames(sorted_df) <- c("A1", "A2")
步骤3:统计合并后的频次
用你熟悉的plyr::count()函数统计即可:
library(plyr) count(sorted_df, c("A1", "A2"))
运行后会得到你想要的结果:
A1 A2 freq 1 A A 1 2 A B 3 3 C D 4
可选:用dplyr实现(更现代的tidyverse风格)
如果你习惯用tidyverse工具链,也可以这样写,逻辑更直观:
library(dplyr) library(tidyr) df %>% # 按行处理 rowwise() %>% # 将排序后的因子拼接成一个字符串,标记为同一个配对 mutate(pair = paste(sort(c(A1, A2)), collapse = "-")) %>% # 取消按行处理 ungroup() %>% # 统计每个配对的频次 count(pair) %>% # 将拼接的字符串拆回两列 separate(pair, into = c("A1", "A2"), sep = "-")
这个方法也会得到完全一致的结果,适合已经在使用tidyverse的场景。
内容的提问来源于stack exchange,提问作者Gaston Castillo
相关产品推荐
相关产品推荐

