You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

统计矩阵中行与列的类别值无序转换次数(含未出现转换)

统计矩阵/数据框中无序值转换的总次数(含未发生转换)

先看你给的示例矩阵,我们先把它创建出来看看结构:

mat <- matrix(c(2, 1, 2, 1, 3, 1, 2, 1, 2), nrow = 3)
mat
#      [,1] [,2] [,3]
# [1,]    2    1    2
# [2,]    1    3    1
# [3,]    2    1    2

你的需求很明确:要统计所有相邻元素(行方向左右、列方向上下)的无序转换次数,而且得把所有可能的元素组合都列出来——哪怕某个转换实际没发生,也要标记次数为0,最终输出成cat1 cat2 n的三列格式。

接下来我一步步给你实现:

步骤1:提取所有相邻元素对

我们需要把行内的左右相邻对、列内的上下相邻对都提取出来,然后合并到一起:

# 提取行向相邻对(每一行的第1-2个、第2-3个元素配对)
row_pairs <- lapply(1:nrow(mat), function(i) cbind(mat[i, -ncol(mat)], mat[i, -1]))
row_pairs <- do.call(rbind, row_pairs)

# 提取列向相邻对(每一列的第1-2个、第2-3个元素配对)
col_pairs <- lapply(1:ncol(mat), function(j) cbind(mat[-nrow(mat), j], mat[-1, j]))
col_pairs <- do.call(rbind, col_pairs)

# 合并行向和列向的所有相邻对
all_pairs <- rbind(row_pairs, col_pairs)

步骤2:把成对元素转为无序格式

因为是无序转换,比如1→2和2→1属于同一种转换,所以我们把每一对的两个元素按从小到大排序,统一格式:

# 对每一对元素排序,确保cat1 <= cat2
ordered_pairs <- t(apply(all_pairs, 1, sort))

步骤3:生成所有可能的元素组合

先找出矩阵里的所有唯一值,然后生成所有无序的两两组合(包括元素和自身配对的情况):

# 获取矩阵中所有唯一值并排序
unique_vals <- sort(unique(c(mat)))

# 生成所有可能的无序组合(含自身配对)
all_possible_pairs <- expand.grid(cat1 = unique_vals, cat2 = unique_vals)
# 只保留cat1 <= cat2的无序组合,避免重复
all_possible_pairs <- all_possible_pairs[all_possible_pairs$cat1 <= all_possible_pairs$cat2, ]

步骤4:统计次数并补全未发生的转换

现在统计实际出现的无序对次数,再和所有可能组合合并,把没出现的转换次数设为0:

# 统计实际出现的无序对次数
pair_counts <- as.data.frame(table(ordered_pairs))
colnames(pair_counts) <- c("cat1", "cat2", "n")
# 把因子类型转为整数,方便后续合并
pair_counts$cat1 <- as.integer(as.character(pair_counts$cat1))
pair_counts$cat2 <- as.integer(as.character(pair_counts$cat2))

# 合并到所有可能组合,缺失的次数填充为0
result <- merge(all_possible_pairs, pair_counts, by = c("cat1", "cat2"), all.x = TRUE)
result$n[is.na(result$n)] <- 0

# 按cat1和cat2排序,和你期望的格式一致
result <- result[order(result$cat1, result$cat2), ]
rownames(result) <- NULL

最后看一下结果,完全符合你的要求:

result
#   cat1 cat2 n
# 1    1    1 0
# 2    1    2 8
# 3    1    3 4
# 4    2    2 0
# 5    2    3 0
# 6    3    3 0

顺便解释下你提到的1-3转换次数为4的原因:行方向里第二行有1↔3和3↔1各1次,列方向里第二列有1↔3和3↔1各1次,总共4次,排序后都归为1-3,所以次数是4。

内容的提问来源于stack exchange,提问作者Thomas White

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:23:31