查找列之间的匹配模式并计算一列中每个不同的元素
Find matching pattern between columns and count for each distinct element in one column
我有一个包含大约 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 个不同的值)
谢谢!
为此我们可以使用 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 列条目来计算与第二个 ":"
之后的条目匹配的数量。
这 returns 匹配 作为 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)
可以先使用 gsub
在 column1
中的第二个 :
之后提取 FirstElement
。然后使用 dplyr
的解决方案可以是对 column2 进行分组(例如 V2
),然后将 V2
与 FirstElement
匹配和不匹配计算为:
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)
$ cat tst.awk
BEGIN { FS="[:\t]" }
prev != $NF { if (NR>1) prt(); prev = $NF }
{ cnt[ == $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
由于你的文件很大,上面使用了键值(每行的最后一个数字)被组合在一起的事实,这样我们就可以在当前键值改变时打印结果而不是存储数据对于数组中的所有键值,然后在文件末尾打印它。
我有一个包含大约 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 个不同的值)
谢谢!
为此我们可以使用 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 列条目来计算与第二个 ":"
之后的条目匹配的数量。
这 returns 匹配 作为 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)
可以先使用 gsub
在 column1
中的第二个 :
之后提取 FirstElement
。然后使用 dplyr
的解决方案可以是对 column2 进行分组(例如 V2
),然后将 V2
与 FirstElement
匹配和不匹配计算为:
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)
$ cat tst.awk
BEGIN { FS="[:\t]" }
prev != $NF { if (NR>1) prt(); prev = $NF }
{ cnt[ == $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
由于你的文件很大,上面使用了键值(每行的最后一个数字)被组合在一起的事实,这样我们就可以在当前键值改变时打印结果而不是存储数据对于数组中的所有键值,然后在文件末尾打印它。