如何防止'read.table'将下划线和连字符改为点号?

14

我有一堆文件需要合并到一个数据框架中。文件名如下:unc.edu.b6530750-0410-43ec-bb79-f862ca3424a6.1918120.rsem.genes.results。

我希望文件名成为列名。我正在使用以下代码:

for (file in file_list){

  if (!exists("dataset")){
      dataset <- read.table(file, header=TRUE, colClasses = c(rep("character", 2),                     rep("NULL", 2)), col.names = c("gene_id", deparse(substitute(file)), "NuLL", "NULL"), sep="\t")
      print(deparse(substitute(file)))
    }

    if (exists("dataset")){
      temp_dataset <-read.table(file, header=TRUE, colClasses = c(rep("character", 2), rep("NULL", 2)), col.names = c("gene_id", deparse(substitute(file)), "NuLL", "NULL"), sep="\t")
      print(deparse(substitute(file)))
      dataset<-merge(dataset, temp_dataset, by = "gene_id")
      rm(temp_dataset)
    }
}

除了列名现在被点替换掉下划线外,一切进展顺利。

colnames(data)

[1] "gene_id"                                                                       
[2] "X...unc.edu.02cb8dbe.ef56.471c.b52d.41c29219fd95.1794854.rsem.genes.results..x"
[3] "X...unc.edu.02cb8dbe.ef56.471c.b52d.41c29219fd95.1794854.rsem.genes.results..y"
[4] "X...unc.edu.02f5dcba.bdcc.4424.aed4.195a8d551325.2085643.rsem.genes.results."  

有关导致这种情况的任何解释都将很有帮助,因为我稍后需要使用另一个文件更改这些名称。


19
尝试:read.table(file, ..., check.names=FALSE)意思是在读取数据时不检查列名是否合法。 - akrun
@akrun 谢谢,可以了! - paul_dg
1个回答

6

如评论中@akrun所述,使用read.table(file, ..., check.names=FALSE)可以解决当前问题。

但是,现在有更简洁的方法可以使用一些tidyverse软件包来实现你想要做的事情。

首先让我们加载软件包并生成一些示例数据:

library(purrr)
library(readr)
data <- c("gene_id\tresult\trandom_a\trandom_b
TNF\t1e-8\t1.7\t4.3
IL8\t0.4\t-0.3\t8.6",
"gene_id\tresult\trandom_a\trandom_b
TNF\t2.4e-7\t1.7\t4.3
IL8\t0.9\t0.8\t8.3",
"gene_id\tresult\trandom_a\trandom_b
TNSF8\t0.003\t2.1\t9.7
IL8\t0.02\t1.9\t4.6")
file_list <- sprintf("file_%d.csv", 1:3)
walk2(data, file_list, ~write_tsv(read_tsv(.x), .y))

现在是读取和合并数据的实际部分:
library(purrr)
library(readr)
library(dplyr)
dataset <- file_list %>%
  map(~read_tsv(.x, col_types = "cc__", col_names = c("gene_id", .x), skip = 1)) %>%
  reduce(full_join, by = "gene_id")

这段代码使用map函数逐个读取文件,跳过第一行假定为表头和第三、四列,并将结果的列重命名为gene_id和文件名。然后使用dplyr::full_joinpurrr::reduce顺序连接这些结果。虽然这个问题很久以前就被问到了,但这种任务很常见,因此我认为一个基于tidyverse的答案仍然很有用。(而且它仍然在“未回答的带有投票”的筛选器中。)

我不明白为什么这比read.table(file, ..., check.names=FALSE)更“整洁”。但是它更复杂,出错的机会更多,而且肯定有更多的依赖关系。 - Sebastien Renaut
1
@SebastienRenaut 我认为你可能错过了我回答的后半部分的重点;它不是使用 check.names 的替代方案,而是 OP 代码中整个循环的替代方案。它只需要三行代码就能实现原始代码中需要12行才能完成的功能。 - Nick Kennedy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接