如何在R中读取此文件

时间:2015-05-13 21:22:16

标签: r read.table

我有以下文件:

GroupA Whatever1 A B C
GroupB Whatever2 C D
GroupC Whatever3 E F G H

第1列和第2列应作为单独的列读取。每行的其余部分不应在制表符处拆分,而应为第三列。这是一个丑陋的方式:

foo <- read.table( text="GroupA Whatever1 A B C
GroupB Whatever2 C D
GroupC Whatever3 E F G H", fill=T, header=F)
foo2 <- data.frame( foo$V1, foo$V2, 
  V3=apply( foo[,-c(1,2)], 1, 
    function(x) paste0( x, collapse="\t")))

结果是我想要的:

> foo2
  foo.V1    foo.V2         V3
1 GroupA Whatever1  A\tB\tC\t
2 GroupB Whatever2   C\tD\t\t
3 GroupC Whatever3 E\tF\tG\tH

有更好的方法吗?优选地,不需要首先拆分然后再次粘贴柱子?表中的一些行非常非常长。

3 个答案:

答案 0 :(得分:1)

也许使用 tidyr ......?

> library(tidyr)
> unite(foo,foo_all,V3:V6,sep = "\t")
      V1        V2    foo_all
1 GroupA Whatever1  A\tB\tC\t
2 GroupB Whatever2   C\tD\t\t
3 GroupC Whatever3 E\tF\tG\tH

答案 1 :(得分:1)

我会考虑一个字符串分割函数,它允许您指定结果片段的数量。例如,您可以使用“stringi”包中的stri_split_fixed

在此,我假设您已使用readLines从文件中获取文本:

text <- c("GroupA Whatever1 A B C", 
          "GroupB Whatever2 C D", 
          "GroupC Whatever3 E F G H")

library(stringi)

stri_split_fixed(text, " ", 3, simplify = TRUE)
#      [,1]     [,2]        [,3]     
# [1,] "GroupA" "Whatever1" "A B C"  
# [2,] "GroupB" "Whatever2" "C D"    
# [3,] "GroupC" "Whatever3" "E F G H"

从那里开始,如果你真的想在最后一栏用标签替换空格,那应该是一个非常简单的gsub操作。

答案 2 :(得分:0)

为什么不使用awk对数据集进行命令行操作? (或其他语言,如python,perl等)

这是一个awk的解决方案。首先,您需要知道数据集的最大列数:

foo=$(awk "BEGIN{max=0} {if(NF>max) max=NF} END{print max}" dataset_file_name)

现在你可以使用awk脚本,将我们刚刚计算的参数传递给它,并将输出重定向到一个新文件:

awk -f my_script.awk -v max=$foo dataset_file_name > my_new_dataset

在R中,您必须指定分隔符(空格):

bar <- read.table("my_new_dataset", sep=" ")

您将获得与您发布的示例相同的结果。

这里是 my_script.awk 的代码:

{
  printf("%s %s ", $1, $2);
  for(i=3; i<NF; i++) printf("%s/t", $i);
  printf("%s", $NF)
  if(NF<max)
    for(i=1; i<(max=1-NF); i++) printf("\t");
  printf("\n");
}

另一种可能的解决方案是将数据集文件拆分为两个单独的文件,第一个包含前两列,第二个包含所有其他列。这样,您可以更轻松地导入和操作数据集的第三列。

在命令行上:

cut -f -2 dataset_file_name > dataset_columns_1_2
cut -f 3- dataset_file_name > dataset_rest_of_columns

[注意:cut的分隔符为标签,如果列分隔符不同,请使用-d选项(有关详细信息cut --help)。 ]

实际上,通过使用这种方法我看不到任何真正的优势......但我认为cut命令在其他一些场合可能会有用。