【问题标题】:Concatanate two columns in a data.frame/file with 1000 columns to one column in a new data.frame/file将具有 1000 列的 data.frame/file 中的两列连接到新 data.frame/file 中的一列
【发布时间】:2015-01-23 15:47:54
【问题描述】:

在我的问题中,我提到了 data.frame 或文件。这意味着,我会接受 R 和 bash 的解决方案。让我们来解决我的问题。

我有一个 df/文件,它有大约 1000 列和 100000 行。我的任务是从这个 df/file 中取出一个新文件,其中 df1 中的两列合并为一列并用“/”分隔。棘手的是,我希望所有列都使用这个。为了更清楚,这里有一个例子:

df1 有 10 列

a b c d s f r t g g
f j g k r k d a f l 
f p j h g i t b k k
h j l u z b g b d h

我想要的是以下内容:df2 with 5 columns

a/b c/d s/f r/t g/g
f/j g/k r/k d/a f/l 
f/p j/h g/i t/b k/k
h/j l/u z/b g/b d/h

我知道我可以将两列用“/”分隔,并使用粘贴功能。但不幸的是,我不知道如何将它与多列一起使用。也许可以使用“for循环”?

我可以想象对于 bash,awk 是解决方案,但我不知道它是如何正常工作的。因为我有非常大的文件,我猜 bash 是更快的方法。

提前感谢您帮助我。

最好, 托比

【问题讨论】:

    标签: r bash function awk paste


    【解决方案1】:

    你可以试试

    df1 <- df[c(TRUE,FALSE)]
    df2 <- df[c(FALSE,TRUE)]
    as.data.frame(mapply(paste, df1, df2, sep="/"))
    #   V1  V3  V5  V7  V9
    #1 a/b c/d s/f r/t g/g
    #2 f/j g/k r/k d/a f/l
    #3 f/p j/h g/i t/b k/k
    #4 h/j l/u z/b g/b d/h
    

    或者你可以这样做

    as.data.frame(`dim<-`(paste(as.matrix(df1), 
                    as.matrix(df2), sep="/"), dim(df1)))
    

    【讨论】:

    • 值得注意的是,data.framematrix 之间的转换消耗了第二个解决方案运行时间的 80%,因此我建议 @Tobias 尽可能避免使用 data.frame。跨度>
    【解决方案2】:

    如果你更喜欢使用文件,你可以使用 perl:

    cat x.txt | perl -ne '$count = 1; s/ /(++$count % 2 == 0)?"\/":$&/ge;print'
    

    为了了解这个解决方案的性能,我生成了一个大数据框:

    d <- as.data.frame(matrix(sample(letters,size = 10^3*10^5,replace=T,),ncol=10^5))
    

    将其保存为文本文件,并启动 perl one-liner,在我的机器上花了 47.5 秒。

    为了比较,我还评估了akrun的解决方案system.time(df3 &lt;- as.data.frame(mapply(paste, df1, df2, sep="/")))的运行时间,耗时210.6秒,即4-5倍。 akrun 建议的另一个解决方案 as.data.frame(dim(paste(as.matrix(df1), as.matrix(df2), sep="/"), dim(df1))) 可以在 59.7 秒内完成。

    【讨论】:

      猜你喜欢
      • 2018-05-25
      • 2017-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-17
      • 1970-01-01
      • 2013-12-20
      • 1970-01-01
      相关资源
      最近更新 更多