换号长列表

时间:2018-06-20 18:50:59

标签: r perl transpose

我有一个Excel CSV文件,在单列中有一长串数字,用空格隔开:

6.83E-05 1.93E-04 4.36E-04 7.17E-04 1.04E-03 1.37E-03 1.30E-03 1.39E-03 1.34E-03 1.34E-03 1.58E-03 1.30E-03 8.82E-04 1.09E-03 9.61E-04 8.19E-04 7.03E-04 6.21E-04 5.54E-04 4.98E-04

2.56E-05 7.33E-05 1.63E-04 2.63E-04 3.79E-04 5.03E-04 4.83E-04 5.45E-04 5.76E-04 6.33E-04 8.06E-04 7.36E-04 5.43E-04 6.69E-04 6.12E-04 5.36E-04 4.66E-04 4.13E-04 3.66E-04 3.27E-04

我想重新组织它,使它们看起来像这样:

6.83E-05 2.56E-05 1.93E-04 7.33E-05 4.36E-04 1.63E-04 7.17E-04 2.63E-04 1.04E-03 3.79E-04 1.37E-03 5.03E-04 1.30E-03 4.83E-04 1.39E-03 5.45E-04 1.34E-03 5.76E-04 1.34E-03 6.33E-04 1.58E-03 8.06E-04 1.30E-03 7.36E-04 8.82E-04 5.43E-04 1.09E-03 6.69E-04 9.61E-04 6.12E-04 8.19E-04 5.36E-04 7.03E-04 4.66E-04 6.21E-04 4.13E-04 5.54E-04 3.66E-04 4.98E-04 3.27E-04

我正在使用Perl或R进行此操作。在这种情况下,R转置函数可以工作吗?我尝试了awk,但这似乎没用。

3 个答案:

答案 0 :(得分:1)

这是一个由另一个问题改编的perl解决方案(ikegami解决方案)。它输出一个csv文件。

#!/usr/bin/perl
use strict;
use warnings;
use List::UtilsBy::XS 'zip_by';

# adapted method by ikegami
# http://stackoverflow.com/questions/37288627/how-to-read-every-3-lines-in-perl/37289263#37289263

my @in = split /\n/, <<EOF;
6.83E-05
1.93E-04
4.36E-04
7.17E-04
1.04E-03
1.37E-03
1.30E-03
1.39E-03
1.34E-03
1.34E-03
1.58E-03
1.30E-03
8.82E-04
1.09E-03
9.61E-04
8.19E-04
7.03E-04
6.21E-04
5.54E-04
4.98E-04

2.56E-05
7.33E-05
1.63E-04
2.63E-04
3.79E-04
5.03E-04
4.83E-04
5.45E-04
5.76E-04
6.33E-04
8.06E-04
7.36E-04
5.43E-04
6.69E-04
6.12E-04
5.36E-04
4.66E-04
4.13E-04
3.66E-04
3.27E-04
EOF

my $rec = [];
my @data = $rec;

for (@in) {
    if (/^\s*$/) {
        $rec = [];
        push @data, $rec;
    }
    else {
        push @$rec, $_;
    }
}   

print zip_by { join(",", @_) . "\n"} @data;

更新:鉴于输入已更改,这是一种更简单的解决方案。 (89行和〜171行)

my @data;
my $i = 0;

for (@in) {
    if (/^\s*$/) {
        $i = 0;
    }
    else {
        push @{ $data[$i++] }, $_;
    }
}   

for my $aref (@data) {
    print join(",", @$aref), "\n";  
}

输出:

6.83E-05,2.56E-05
1.93E-04,7.33E-05
4.36E-04,1.63E-04
7.17E-04,2.63E-04
1.04E-03,3.79E-04
1.37E-03,5.03E-04
1.30E-03,4.83E-04
1.39E-03,5.45E-04
1.34E-03,5.76E-04
1.34E-03,6.33E-04
1.58E-03,8.06E-04
1.30E-03,7.36E-04
8.82E-04,5.43E-04
1.09E-03,6.69E-04
9.61E-04,6.12E-04
8.19E-04,5.36E-04
7.03E-04,4.66E-04
6.21E-04,4.13E-04
5.54E-04,3.66E-04
4.98E-04,3.27E-04

答案 1 :(得分:0)

如果您确定要在第1列中输入上半部分,而在第2列中输入下半部分,则可以使用matrix进行操作。

Input = read.csv("Input.csv", header=FALSE)
M = matrix(Input$V1, ncol=2)
          [,1]     [,2]
 [1,] 6.83e-05 2.56e-05
 [2,] 1.93e-04 7.33e-05
 [3,] 4.36e-04 1.63e-04
 [4,] 7.17e-04 2.63e-04
 [5,] 1.04e-03 3.79e-04
 [6,] 1.37e-03 5.03e-04
 [7,] 1.30e-03 4.83e-04
 [8,] 1.39e-03 5.45e-04
 [9,] 1.34e-03 5.76e-04
[10,] 1.34e-03 6.33e-04
[11,] 1.58e-03 8.06e-04
[12,] 1.30e-03 7.36e-04
[13,] 8.82e-04 5.43e-04
[14,] 1.09e-03 6.69e-04
[15,] 9.61e-04 6.12e-04
[16,] 8.19e-04 5.36e-04
[17,] 7.03e-04 4.66e-04
[18,] 6.21e-04 4.13e-04
[19,] 5.54e-04 3.66e-04
[20,] 4.98e-04 3.27e-04

如果要使用新结构将其写回到csv,可以使用:

write.table(M, "Input2.csv", row.names=FALSE, col.names=FALSE, sep=",")

答案 2 :(得分:0)

谢谢。因此,使用R我跑了:

Input = read.csv("RawOutput.csv", header=FALSE) M = matrix(Input$V1, nrow= 89, ncol=171)

它给了我想要的输出,共有89行和171列。但是,可能会有一些不同长度的输入文件。它们可能需要多于或少于171列(尽管它们总是有89行)。

是否有一种方法可以告诉R在到达标记(例如,最后一个单元格中的puttng“ EOF”)时停止处理输入的CSV?否则,它将再次循环到开头,并不断增加列数,直到使用ncol指定的数字为止。