如何从含大量空值的R DataFrame生成无冗余EdgeList?
问题描述
- 手头有一份用于网络分析的大型CSV数据集,包含56400行、1330列,绝大多数字段为空
- 目标是将数据集处理成仅含2列的DataFrame,作为网络分析用的EdgeList
- 现有代码无法识别空/空白字段,导致生成的EdgeList包含大量空字段组合,体积异常庞大
- 尝试将空白字段转为NA,但转换后是字符型的
<NA>而非真正的逻辑型NA,问题未解决
现有代码如下:
# 读取数据集 mydf <- read.csv("....\\clean5.csv", header = TRUE, sep = ";", encoding = "UTF-8") # 尝试生成不含空白字段的EdgeList edgelist <- testdf %>% apply(., 1, function(.x){ .x[!is.na(.x)] %>% combn(2) %>% t() %>% as.data.frame() }) %>% do.call(rbind, .)
数据样例(dput输出):
test <- structure(list( X1 = c("A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A ", "A "), X2 = c("B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B"), X3 = c("", "C ", "", "C ", "", "C ", "", "C ", "", "C ", "", "C ", "", "C ", "", "C ", "", "C ", "", "C "), X4 = c("", "", "D", "", "", "", "D", "", "", "", "D", "", "", "", "D", "", "", "", "D", ""), X5 = c("", "", "E ", "", "", "", "E ", "", "", "", "E ", "", "", "", "E ", "", "", "", "E ", ""), X6 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X7 = c("", "", "G ", "", "", "", "G ", "", "", "", "G ", "", "", "", "G ", "", "", "", "G ", ""), X8 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "A ", "A ", "A ", "A ", "A ", "", ""), X9 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "B", "B", "B", "B", "B", "", ""), X10 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "C ", "", "C ", "", "C ", "", ""), X11 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "D", "", "", "", "", ""), X12 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "E ", "", "", "", "", ""), X13 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X14 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "G ", "", "", "", "", ""), X15 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "A ", "A ", "A ", "A ", "A ", "", ""), X16 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "B", "B", "B", "B", "B", "", ""), X17 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "C ", "", "C ", "", "C ", "", ""), X18 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "D", "", "", "", "", ""), X19 = c("", "", "", "", "", "", "", "", "", "", "", "", "", "", "E ", "", "", "", "", ""), X20 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, FALSE, NA, NA, NA, NA, NA) ), row.names = c(NA, 20L), class = "data.frame")
解决方案
核心问题是数据里同时存在三种无效值:真正的NA、空字符串""、非字符型异常值(比如X20里的FALSE),且有效内容还带首尾空格。需要先统一清理所有无效值为真正的NA,再生成EdgeList。
步骤1:统一清理无效值
library(dplyr) library(tidyr) # 清理数据:转空字符串为NA,清理首尾空格,统一非字符异常值为NA clean_df <- test %>% mutate(across(everything(), function(col) { # 先把非字符型转为字符 col <- as.character(col) # 清理内容首尾的空格 col <- trimws(col) # 把空字符串替换为真正的NA col[col == ""] <- NA return(col) }))
步骤2:生成纯净的EdgeList
# 生成仅含有效节点组合的EdgeList edgelist <- clean_df %>% rowwise() %>% # 获取当前行所有非NA的有效节点 mutate(non_na_nodes = list(na.omit(c_across(everything())))) %>% # 只保留有至少2个有效节点的行(否则无法生成两两组合) filter(length(non_na_nodes) >= 2) %>% # 生成节点的两两组合 mutate(edges = list(t(combn(non_na_nodes, 2)))) %>% # 把组合展开为多行 unnest(edges) %>% # 整理为from/to两列的格式 transmute(from = edges[,1], to = edges[,2]) %>% ungroup()
原代码失效原因
- 原代码仅过滤了
!is.na(.x),但数据里大量空字符串""不属于NA,会被保留并参与组合 - 你之前尝试转空白为NA时,错误地生成了字符型的
<NA>字符串,而非直接赋值为真正的NA值
内容的提问来源于stack exchange,提问作者Rumo
相关产品推荐
相关产品推荐

