比较每行的两列中的字符 - 查找不匹配的内容

时间:2014-09-16 23:16:16

标签: r

我可以想到几种令人费解的方法来做到这一点,但最有效的是什么?我的数据集可能有超过10,000行。

示例数据:

example = structure(list(set = structure(c(2L, 2L, 7L, 11L, 11L, 2L, 2L, 
6L, 11L, 12L), .Names = c("87", "89", "90", "91", "92", "93", 
"563", "564", "565", "95"), .Label = c("A/C", "A/G", "A/T", "C/A", 
"C/G", "C/T", "G/A", "G/C", "G/T", "T/A", "T/C", "T/G"), class = "factor"), 
    line1 = c("G", "G", "A", "C", "C", "A", "A", "T", "C", "G"
    ), line2 = c("A", "A", "G", "T", "T", "G", "G", "C", "T", 
    "A")), .Names = c("set", "line1", "line2"), row.names = c(5L, 
7L, 8L, 9L, 10L, 11L, 13L, 14L, 15L, 16L), class = "data.frame")

看起来像:

> example
   set line1 line2
5  A/G     G     A
7  A/G     G     A
8  G/A     A     G
9  T/C     C     T
10 T/C     C     T
11 A/G     A     G
13 A/G     A     G
14 C/T     T     C
15 T/C     C     T
16 T/G     G     A

我想找到第1行和第2行中的字符不在" set"中的行。柱。理想的输出将是这样的:

   set line1 line2 check
5  A/G     G     A  TRUE
7  A/G     G     A  TRUE
8  G/A     A     G  TRUE
9  T/C     C     T  TRUE
10 T/C     C     T  TRUE
11 A/G     A     G  TRUE
13 A/G     A     G  TRUE
14 C/T     T     C  TRUE
15 T/C     C     T  TRUE
16 T/G     G     A FALSE

我想我需要将每一套解析成某种东西......但我有点卡住了。也许这个:

strsplit(as.character(example$set), "/")

然后使用setdiff?

3 个答案:

答案 0 :(得分:2)

这应该是可扩展的,包括任意数量的line1 / 2 / n变量:

with(example, mapply(
  function(x,...) length(setdiff(x,c(...))) == 0, 
  strsplit(as.character(set),"/"), 
  line1,
  line2
))

# [1]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE

答案 1 :(得分:2)

您可以避免字符比较,并使用更多数值方法和这样的策略

#create factors, set up loop up table
g <- setNames(2^((1:4)-1), c("A","C","G","T"))
gg <- setNames(
    c(outer(as.numeric(g), as.numeric(g), bitwOr)),
    outer(names(g), names(g), paste, sep="/")
)

这将A,C,G,T重新编码为1,2,4,8。然后我们将这些值按位“或”一起用于基因型。这基本上将值转换为4个标记,用于跟踪哪些等位基因存在于哪种基因型中。

example$check <- apply(mapply(bitwAnd, 
    lapply(example[,2:3], function(x) g[x]), 
    MoreArgs=list(gg[as.character(example$set)])), 1, all)

我们使用内部lapply()将示例中的ACTG转换为数字等价物。然后我们使用mapply来按位和每个单值使用set列,以确保每个等位基因都存在于基因型中。最后,我们进行总体apply以验证两个等位基因都在基因型中。这给了我们

   set line1 line2 check
5  A/G     G     A  TRUE
7  A/G     G     A  TRUE
8  G/A     A     G  TRUE
9  T/C     C     T  TRUE
10 T/C     C     T  TRUE
11 A/G     A     G  TRUE
13 A/G     A     G  TRUE
14 C/T     T     C  TRUE
15 T/C     C     T  TRUE
16 T/G     G     A FALSE

答案 2 :(得分:0)

这对你有用吗?

L <- 1:dim(example)[1]
in1 <- sapply(L, function(i) length(grep(example$line1[i], example$set[i])))
in2 <- sapply(L, function(i) length(grep(example$line2[i], example$set[i])))
example$check <- in1 & in2