如何基于条件求和将给定DataFrame转换为目标方阵?
解决方案:从原始DataFrame生成目标共现方阵
嘿,这个问题本质是计算变量间的共现次数——也就是当某个变量取值为1时,另一个变量也取值为1的样本数量,同时对角线设为0(排除自身统计)。下面是具体实现步骤,完全贴合你的需求:
首先,我们先加载需要的包并定义原始数据:
library(tidyverse) df <- tribble( ~ID, ~V1, ~V2,~V3, '1', NA,1, NA, '2', 1,1,NA, '3', 1,NA,NA, '4', NA,NA,1, '5', 1,1,1, '6',NA,NA,1, '7',1,NA,1 )
接下来分四步完成转换:
- 替换NA为0:原始数据中的NA表示变量取值不为1,我们把它转换成0,这样后续求和时不会被NA干扰:
df_num <- df %>% select(V1:V3) %>% # 只保留需要计算的变量列 mutate(across(everything(), ~replace_na(.x, 0))) # 把所有NA替换成0
- 计算变量交叉共现矩阵:用矩阵的交叉乘积
t(mat) %*% mat,这个操作会自动统计每对变量的共现次数——比如结果中V1行V2列的数值,就是所有V1=1的样本中V2=1的数量:
cross_mat <- t(as.matrix(df_num)) %*% as.matrix(df_num)
- 设置对角线为0:因为我们不需要统计变量自身的共现(比如V1=1时V1=1的次数),所以把矩阵的对角线元素全部设为0:
diag(cross_mat) <- 0
- 转换为目标DataFrame格式:把矩阵转回DataFrame,并添加
Var列存储行名:
df2 <- cross_mat %>% as.data.frame() %>% rownames_to_column("Var")
现在你可以查看df2,它完全符合你给出的目标结构:
> df2 Var V1 V2 V3 1 V1 0 2 1 2 V2 2 0 1 3 V3 1 1 0
这个方法高效且简洁,利用了矩阵运算的特性来避免循环,非常适合这类变量共现统计的场景。
内容的提问来源于stack exchange,提问作者Misha
相关产品推荐
相关产品推荐

