【问题标题】:print first 8 columns and one of the last three non-zero columns linux/awk/sed/R [closed]打印前 8 列和最后三个非零列之一 linux/awk/sed/R [关闭]
【发布时间】:2019-02-04 16:12:40
【问题描述】:

我想打印文件的前 8 列和后 3 列中的一列,这些列具有非零值。示例输入:

chr2    219541089   C   15  0   12  0   3   0   0   20
chr20   31831068    C   48  3   45  0   0   6.25    0   0
chr20   38724789    C   41  4   37  0   0   9.7561  0   0
chr20   63080141    C   95  0   91  4   0   0   4.21053 0
chr22   37642528    C   31  2   29  0   0   6.45161 0   0

想要的输出:

chr2    219541089   C   15  0   12  0   3   20
chr20   31831068    C   48  3   45  0   0   6.25
chr20   38724789    C   41  4   37  0   0   9.7561
chr20   63080141    C   95  0   91  4   0   4.21053
chr22   37642528    C   31  2   29  0   0   6.45161

任何帮助将不胜感激!谢谢

【问题讨论】:

标签: r linux awk sed


【解决方案1】:

更基本的解决方案可能是

cbind(df[,1:8], pmax(df[,9], df[,10], df[,11]))

df 是你的数据框。

【讨论】:

  • 非常感谢马丁如此快速简单的回复!
  • 需要说明的是,如果最右边的三行有可能同时为负数,它就行不通了。
  • 当然,马丁,我明白了。谢谢!另外,是否可以修改以将相应的列名也打印为单独的列?
【解决方案2】:

将 0 替换为 NA 后,我们可以 coalesce 。在mutate_at 中选择感兴趣的列 (9:11) 后,用replace 将 0 替换为 NA,然后通过删除每行中的 NA 并从列中选择第一个非 NA 元素,使用mutate 创建一个新列9 到 11 (coalesce) 并使用 select 删除不需要的列

library(dplyr)
df1 %>%
    mutate_at(9:11, funs(replace(., .==0, NA_real_))) %>%
    mutate(colN = coalesce(!!! rlang::syms(names(.)[9:11]))) %>%
    select(-(9:11))
#    v1        v2 v3 v4 v5 v6 v7 v8     colN
#1  chr2 219541089  C 15  0 12  0  3 20.00000
#2 chr20  31831068  C 48  3 45  0  0  6.25000
#3 chr20  38724789  C 41  4 37  0  0  9.75610
#4 chr20  63080141  C 95  0 91  4  0  4.21053
#5 chr22  37642528  C 31  2 29  0  0  6.45161

数据

df1 <- structure(list(v1 = c("chr2", "chr20", "chr20", "chr20", "chr22"
), v2 = c(219541089L, 31831068L, 38724789L, 63080141L, 37642528L
), v3 = c("C", "C", "C", "C", "C"), v4 = c(15L, 48L, 41L, 95L, 
31L), v5 = c(0L, 3L, 4L, 0L, 2L), v6 = c(12L, 45L, 37L, 91L, 
29L), v7 = c(0L, 0L, 0L, 4L, 0L), v8 = c(3L, 0L, 0L, 0L, 0L), 
v9 = c(0, 6.25, 9.7561, 0, 6.45161), v10 = c(0, 0, 0, 4.21053, 
0), v11 = c(20L, 0L, 0L, 0L, 0L)), class = "data.frame", 
row.names = c(NA, -5L))

【讨论】:

  • 感谢 akrun 这么快的回答!你能解释一下吗,因为我是 R 的新手!
  • @aan 当然,我用一些描述更新了解决方案
  • 感谢您的详细回复!
【解决方案3】:

使用 awk

awk '{$(NF-2) = $(NF-2) ? $(NF-2) : ($(NF-1) ? $(NF-1) : $NF); $(NF-1) = $NF = ""}1' file

或 perl(假设最后 3 个值中有 1 个不为零)

perl -lane '@first = splice @F,0,8; print "@{[ @first, grep {$_} @F ]}"' file

将输出通过管道传输到| column -t 以使其更漂亮。

【讨论】:

    【解决方案4】:

    另一个awk

    $ awk -v OFS='\t' 'function zv(x,y) {return x?x:y} 
                       {v=zv($(NF-2),zv($(NF-1),$NF)); NF-=2; $NF=v}1' file
    
    chr2    219541089       C       15      0       12      0       3       20
    chr20   31831068        C       48      3       45      0       0       6.25
    chr20   38724789        C       41      4       37      0       0       9.7561
    chr20   63080141        C       95      0       91      4       0       4.21053
    chr22   37642528        C       31      2       29      0       0       6.45161
    

    取第一个非零值,以防有多个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-08
      • 2015-11-04
      • 2014-03-24
      • 2019-11-06
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多