【问题标题】:Comparing exact values with many significant digits across columns将精确值与跨列的许多有效数字进行比较
【发布时间】:2019-07-03 20:30:37
【问题描述】:

我有一张包含许多不同有效数字的数字表。我需要跨列找到这些数字的完全匹配 - 例如

find_mz_matches <- data.frame("mz1" = c(3.14222, 314.12003, 214.220, 
254.111223, NA, NA, NA, NA, NA), "mz2" = c(3.14222, 456.2200001, NA, 
NA, NA, NA, NA, NA, NA), "mz3" = c(300.112223, 456.2200001, 3.14222, 
254.111223, 900.232, 476.0012503, 459.00201, 500.60402, 300.4053102))

我想知道 mz1 和 mz2、mz2 和 mz3 之间以及最后所有三列之间共享哪些值。

因此,比较 mz1 和 mz2 应该得出:

 mz1_v_mz2
 3.14222
 456.2200001

并比较所有三个:

mz_all
3.14222

我拼凑了一些几乎可以工作的东西,但问题是它在某个地方四舍五入,我的输出包括相似但不相同的数字,例如3.14222 不应与 3.14223 匹配。它还在输出中包含 NA,这是不需要的。

duplicates_across1 <- find_mz_matches[find_mz_matches$mz1 
%in% find_mz_matches$mz2, ]

这应该可以比较前两列,所以我想我会获取输出并再次进行下一次比较 - 将duplicates_across1的输出与find_mz_matches$mz3进行比较。出于某种原因,它没有在所有三列之间捕捉到 3.14222 的存在,我不知道为什么。

duplicates_all <- duplicates_across1[duplicates_across1$mz1 
%in% find_mz_matches$mz3, ]

【问题讨论】:

    标签: r filtering data-manipulation


    【解决方案1】:

    这是一个非常 lapply-y 的答案,它比较每个组合并将结果存储在列表中。如果您也有超过 3 列,它应该是灵活的。祝你好运!

    # Creating all combinations of columns in a list (and flattening it with unlist)
    combos <- unlist(lapply(2:ncol(find_mz_matches), combn, x = find_mz_matches, simplify = F), recursive = F)
    
    # Checking for common elements
    common_elements <- lapply(combos, function(x) Reduce(base::intersect, x))
    
    # Renaming the elements
    names(common_elements) <- sapply(lapply(combos, names), paste, collapse = "_")
    
    common_elements
    $mz1_mz2
    [1] 3.14222      NA
    
    $mz1_mz3
    [1]   3.14222 254.11122
    
    $mz2_mz3
    [1]   3.14222 456.22000
    
    $mz1_mz2_mz3
    [1] 3.14222
    

    【讨论】:

      【解决方案2】:

      Reduce():

      Reduce(intersect, find_mz_matches, accumulate = T)
      Reduce(intersect, find_mz_matches, accumulate = T, right = T)
      

      accumulate 参数是可选的 - 它只是用来向您展示正在发生的事情。供您使用,您可以将其取出,它会导致 3.14222。

      Reduce(intersect, find_mz_matches)
      [1] 3.14222
      

      【讨论】:

        【解决方案3】:

        我会这样做:

        find_mz_matches <- data.frame("mz1" = c(3.14222, 314.12003, 214.220, 
                                                254.111223, NA, NA, NA, NA, NA), "mz2" = c(3.14222, 456.2200001, NA, 
                                                                                           NA, NA, NA, NA, NA, NA), "mz3" = c(300.112223, 456.2200001, 3.14222, 
                                                                                                                              254.111223, 900.232, 476.0012503, 459.00201, 500.60402, 300.4053102))
        find_mz_matches$mz_allmz1mz2 <- ifelse(find_mz_matches$mz1 == find_mz_matches$mz2 ,find_mz_matches$mz1   , NA)
        find_mz_matches$mz_allmz2mz3 <- ifelse(find_mz_matches$mz2 == find_mz_matches$mz3 ,find_mz_matches$mz2   , NA)
        

        之后,如果不存在冲突,我将合并结果列。

        【讨论】:

        • 感谢您的意见,但似乎仍有问题。第三行返回错误 Error in $&lt;-.data.frame(*tmp*, mz_allmz2mz3, value = logical(0)) : replacement has 0 rows, data has 9 这里对顺序有依赖性吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-01-09
        • 2018-05-29
        • 2022-06-17
        • 1970-01-01
        • 2016-03-11
        • 2018-10-31
        • 1970-01-01
        相关资源
        最近更新 更多