查找列之间的匹配模式,并为一列中的每个不同元素计数

时间:2018-07-01 07:51:51

标签: r shell awk cut

我有一个制表符分隔的文件,其中包含大约7000万行,如下所示;

chr1:25851453-25869713W:6655:4522:4234:2258:2508:S      6655
chr1:25851453-25869713W:6655:4523:4234:2258:2508:A      6655
chr1:25851453-25869713W:0000:4524:4234:2258:2508:S      6655
chr1:25851453-25869713W:6655:4525:4234:2258:2508:S      6655
chr1:26235471-26237662W:6663:124:1864:311:455:S         6663
chr1:26235471-26237662W:6663:125:1864:311:455:S         6663

我试图报告第2列中每个不同的元素,第1列中第二个“:”之后的模式与第2列中的模式匹配的次数是多少。

在上面的示例中类似这样;

6655 matches 3
6655 mismatches 1
6663 matches 2
6663 mismatches 0

(具体来说,第2列中有15559个不同的值)

谢谢!

3 个答案:

答案 0 :(得分:0)

我们可以使用strsplit

lapply(setNames(unique(df[, 2]), unique(df[, 2])), function(x)
    sum(x == sapply(strsplit(as.character(df[, 1]), ":"), function(y) y[3])))
#$`6655`
#[1] 3
#
#$`6663`
#[1] 2

说明:我们首先从第2列确定唯一条目;然后,对于每个唯一条目,我们通过在":"上划分第1列条目来计算与第二个":"之后的条目的匹配数。

这将匹配项的数量返回为list

不匹配数量相反的情况很简单,我将由您自己决定。


样本数据

df <- read.table(text =
    "chr1:25851453-25869713W:6655:4522:4234:2258:2508:S 6655
chr1:25851453-25869713W:6655:4523:4234:2258:2508:A 6655
chr1:25851453-25869713W:0000:4524:4234:2258:2508:S 6655
chr1:25851453-25869713W:6655:4525:4234:2258:2508:S 6655
chr1:26235471-26237662W:6663:124:1864:311:455:S 6663
chr1:26235471-26237662W:6663:125:1864:311:455:S 6663", header = F)

答案 1 :(得分:0)

首先可以使用FirstElement提取:中第二个column1之后的gsub。然后,使用dplyr的解决方案可以将第2列分组(例如V2),然后将V2FirstElement的匹配和不匹配计数为:

library(dplyr)

df %>% 
   mutate(FirstElement = gsub("^chr1:[^:]*:(\\d+):.*","\\1",V1)) %>%
  group_by(V2) %>%
  summarise(matches = sum(V2==FirstElement), mismatches = sum(V2!=FirstElement))

# # A tibble: 2 x 3
#      V2 matches mismatches
#   <int>   <int>      <int>
# 1  6655       3          1
# 2  6663       2          0

数据:

df <- read.table(text="
chr1:25851453-25869713W:6655:4522:4234:2258:2508:S 6655
chr1:25851453-25869713W:6655:4523:4234:2258:2508:A 6655
chr1:25851453-25869713W:0000:4524:4234:2258:2508:S 6655
chr1:25851453-25869713W:6655:4525:4234:2258:2508:S 6655
chr1:26235471-26237662W:6663:124:1864:311:455:S 6663
chr1:26235471-26237662W:6663:125:1864:311:455:S 6663",
stringsAsFactors = FALSE)

答案 2 :(得分:0)

$ cat tst.awk
BEGIN { FS="[:\t]" }
prev != $NF { if (NR>1) prt(); prev = $NF }
{ cnt[$3 == $NF]++ }
END { prt() }
function prt() {
    printf "%d matches %d\n", prev, cnt[1]
    printf "%d mismatches %d\n", prev, cnt[0]
    delete cnt
}

$ awk -f tst.awk file
6655 matches 3
6655 mismatches 1
6663 matches 2
6663 mismatches 0

由于您的文件很大,因此上面使用了以下事实:将键值(每行的最后一个数字)组合在一起,以便我们仅在当前键值更改时打印结果,而不是存储所有键的数据键值,然后将其打印在文件末尾。