我有以下文件:
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
有更好的方法吗?优选地,不需要首先拆分然后再次粘贴柱子?表中的一些行非常非常长。
答案 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
命令在其他一些场合可能会有用。