RStudio中For循环生成DataFrame出现多余0行及添加文件名列求助
问题解决与优化方案
一、消除多余0值行的问题
可能原因
- 初始空DataFrame
virus = data.frame()在第一次rbind时,会引入空行导致0值; - 部分txt文件存在空白行,被
read.table读入后,str_count统计结果为0; - 存在空的txt文件,读入后直接生成全0行。
修复步骤及代码
- 改用列表存储中间结果,避免反复
rbind的低效与空行问题; - 读入文件后过滤空行;
- 跳过空内容的文件(可选)。
改进后的for循环代码:
library(stringr) # 初始化列表存储结果 virus_list <- list() for (i in virus_data) { # 读取文件,指定字符串列类型避免自动转换 b <- read.table(i, header = FALSE, colClasses = "character") # 过滤空行 b <- b[nchar(b$V1) > 0, , drop = FALSE] # 跳过空内容的文件 if (nrow(b) == 0) next # 计算各字母概率并添加文件名 old_data <- data.frame( A = str_count(b$V1, "A") / str_length(b$V1), B = str_count(b$V1, "B") / str_length(b$V1), D = str_count(b$V1, "D") / str_length(b$V1), C = str_count(b$V1, "C") / str_length(b$V1), # 用basename提取纯文件名,保留路径则直接写i filename = basename(i) ) # 存入列表 virus_list[[i]] <- old_data } # 合并所有结果为DataFrame并重置行名 virus <- do.call(rbind, virus_list) rownames(virus) <- NULL
二、添加文件名列的最优方法
推荐方案:使用purrr包的map_df函数
这种方式无需手动管理循环与列表,代码更简洁高效,且自动处理文件名关联:
library(purrr) library(stringr) virus <- map_df(virus_data, function(file) { b <- read.table(file, header = FALSE, colClasses = "character") b <- b[nchar(b$V1) > 0, , drop = FALSE] # 空文件直接返回NULL,不参与合并 if (nrow(b) == 0) return(NULL) data.frame( A = str_count(b$V1, "A") / str_length(b$V1), B = str_count(b$V1, "B") / str_length(b$V1), D = str_count(b$V1, "D") / str_length(b$V1), C = str_count(b$V1, "C") / str_length(b$V1), filename = basename(file) ) })
map_df会自动将所有返回的data.frame合并为一个,同时跳过返回NULL的空文件,彻底避免多余行。
补充说明
- 如果需要保留文件的完整路径,将
basename(file)替换为file即可; - 确保提前加载
stringr包(代码中用到了str_count和str_length函数)。
内容的提问来源于stack exchange,提问作者Dun Lang
相关产品推荐
相关产品推荐

