如何基于R数据框的列数据构建存在/缺失(1/0)矩阵或数据框
解决方案
你可以根据自己的使用习惯选择基础R或者tidyverse方案,两种都支持处理列长度不一(短列自动补NA的dataframe,或者原生列表结构)的场景:
方法1:基础R实现(无需安装额外包)
如果你的原始数据是带NA补全的dataframe(长度不一的列会被自动填充NA),直接运行如下代码:
# 提取所有出现过的唯一元素,排除NA all_ele <- sort(unique(na.omit(unlist(df)))) # 逐列判断元素是否存在,转成0/1值 res <- sapply(df, function(col) as.integer(all_ele %in% na.omit(col))) # 设置行名为元素名 rownames(res) <- all_ele # 查看结果 res
如果你的原始数据是列表结构(更适合存储长度不一的列),代码可以简化为:
# 示例列表结构原始数据 df_list <- list( sp1 = c("e1", "e2", "e4"), sp2 = c("e1", "e3", "e4"), sp3 = c("e2", "e3", "e5"), sp4 = c("e1", "e3") ) all_ele <- sort(unique(unlist(df_list))) res <- sapply(df_list, function(col) as.integer(all_ele %in% col)) rownames(res) <- all_ele
方法2:tidyverse实现(语法更灵活易读)
library(tidyverse) res <- df %>% # 把所有列转为长表,自动丢弃NA值 pivot_longer(everything(), values_to = "ele", values_drop_na = TRUE) %>% # 按列名和元素计数 count(name, ele) %>% # 转回宽表,缺失值填充为0 pivot_wider(names_from = name, values_from = n, values_fill = 0) %>% # 把元素列设为行名 column_to_rownames("ele")
测试验证
以你提到的新增长度为2的sp4列场景测试,输入数据如下:
df <- data.frame( sp1 = c("e1", "e2", "e4"), sp2 = c("e1", "e3", "e4"), sp3 = c("e2", "e3", "e5"), sp4 = c("e1", "e3", NA) )
两种方法输出的结果都符合预期:
sp1 sp2 sp3 sp4 e1 1 1 0 1 e2 1 0 1 0 e3 0 1 1 1 e4 1 1 0 0 e5 0 0 1 0
内容的提问来源于stack exchange,提问作者abraham
相关产品推荐
相关产品推荐

