如何在R中格式化CSV文件?将多列数据转为两列结构
R语言数据格式化问题:宽表转两列长表
当前问题
运行现有代码后生成了113列的宽格式数据,而非预期的两列(文件名+对应数值)的长格式结构。
当前输出格式
single.single_one_count1 single.single_one_count2 single.single_one_count3 file_name1 9 15 6 file_name2 9 15 6 file_name3 9 15 6 file_name4 9 15 6 file_name5 9 15 6 file_name6 9 15 6 file_name7 9 15 6 file_name8 9 15 6 single.single_one_count4 single.single_one_count5 single.single_one_count6 file_name1 10 8 11 file_name2 10 8 11 file_name3 10 8 11 file_name4 10 8 11 file_name5 10 8 11 file_name6 10 8 11 file_name7 10 8 11 file_name8 10 8 11 single.single_one_count7 single.single_one_count8 single.single_one_count9 file_name1 12 8 10 file_name2 12 8 10 file_name3 12 8 10 file_name4 12 8 10 file_name5 12 8 10 file_name6 12 8 10 file_name7 12 8 10 file_name8 12 8 10 single.single_one_count10 single.single_one_count11 file_name1 11 4 file_name2 11 4
预期输出格式
filename, value file_name1, 9 file_name2, 9 ...
现有代码
#set the directory containing the TSV files directory <- "C:/Users/tcamp/OneDrive/Desktop/a2_Tom_Campbell_40332657/images" #Use list.files() to get a list of all TSV files in the directory file_names <- list.files(directory, pattern = "\\.tsv$", full.names = TRUE) #function definition to calculate the single_one_count single_one_count <- function(file_name){ #Read in the TSV file as a data frame df <- read.table(file_name, header = TRUE, sep = "\t") #Calculate the number of rows with just one "1" count <- sum(apply(df == 1, 1, all)) return(count) } result_list <- lapply(file_names, single_one_count) result_df <- data.frame(file = c(file_name = file_names), single = c(single_one_count = result_list)) result_df write.csv(result_df, file = "C:/Users/tcamp/OneDrive/Desktop/a2_Tom_Campbell_40332657/40332657_features.csv", row.names = FALSE)
解决方案
1. 修正核心计算逻辑
原函数里的apply(df == 1, 1, all)是计算每行所有元素都是1的行数,和注释里“每行只有一个1”的需求不符,需要替换为rowSums(df == 1) == 1来统计每行恰好有一个1的数量。
2. 修正数据框构建逻辑
result_list是lapply返回的列表,直接放入data.frame会被拆成多列,需要用unlist()转为向量;另外如果只需要文件名而非完整路径,用basename()提取文件名更合适。
修改后的完整代码:
# 设置TSV文件所在目录 directory <- "C:/Users/tcamp/OneDrive/Desktop/a2_Tom_Campbell_40332657/images" # 获取目录下所有TSV文件的完整路径 file_names <- list.files(directory, pattern = "\\.tsv$", full.names = TRUE) # 定义函数:计算每行恰好有一个"1"的行数 single_one_count <- function(file_name){ df <- read.table(file_name, header = TRUE, sep = "\t") # 统计每行等于1的元素个数为1的行数 count <- sum(rowSums(df == 1) == 1) return(count) } # 批量处理所有文件 result_list <- lapply(file_names, single_one_count) # 构建两列的长格式数据框 result_df <- data.frame( filename = basename(file_names), # 提取纯文件名 value = unlist(result_list) # 将列表转为向量 ) # 查看结果 print(result_df) # 导出为CSV write.csv(result_df, file = "C:/Users/tcamp/OneDrive/Desktop/a2_Tom_Campbell_40332657/40332657_features.csv", row.names = FALSE)
解释
rowSums(df == 1)会计算每行中等于1的元素数量,==1筛选出恰好有一个1的行,sum()统计这些行的总数,符合需求。unlist(result_list)将lapply返回的列表转为一维向量,确保数据框中是一列数值而非多列。basename(file_names)从完整路径中提取文件名(比如从C:/xxx/file1.tsv得到file1.tsv),让输出更简洁。
内容的提问来源于stack exchange,提问作者user12540531
相关产品推荐
相关产品推荐

