【问题标题】:Test for equality between all members of list测试列表中所有成员之间的相等性
【发布时间】:2015-12-16 13:34:47
【问题描述】:

检查列表所有成员之间是否相等的正确语法是什么?我发现了

do.call(all.equal, list(1,2,3))

返回TRUE

我的直觉是它检查列表元素内的相等性,而不是之间。

理想情况下,解决方案会忽略元素的名称,但不会忽略元素组件的名称。例如,给定输入,它应该返回 TRUE:

some_list <- list(foo = data.frame(a=1),
                  bar = data.frame(a=1))

但是给定输入是 FALSE:

some_other_list <- list(foo = data.frame(a=1),
                        bar = data.frame(x=1))

但我可以接受一个对元素名称敏感的解决方案。


编辑:显然我需要查看?funprog。作为 accepted 答案的后续行动,值得注意的是以下行为:

Reduce(all.equal, some_list)  # returns TRUE

Reduce(all.equal, some_other_list) #returns [1] "Names: 1 string mismatch"

对于:

yet_another_list <- list(foo = data.frame(a=1),
                        bar = data.frame(x=2))
Reduce(all.equal, yet_another_list)
# returns: [1] "Names: 1 string mismatch"     "Component 1: Mean relative difference: 1"

编辑 2: 我的示例不够充分,Reduce 在 3 个或更多元素的情况下不起作用:

some_fourth_list <- list(foo = data.frame(a=1),
                  bar = data.frame(a=1),
                  baz = data.frame(a=1))
Reduce(all.equal, some_fourth_list) # doesn't return TRUE

【问题讨论】:

    标签: r list


    【解决方案1】:

    1) 如果列表只有问题中的两个组件,请尝试以下操作:

    identical(some_list[[1]], some_list[[2]])
    ## [1] TRUE
    

    2) 或者对于包含任意数量组件的通用方法,请尝试以下操作:

    all(sapply(some_list, identical, some_list[[1]]))
    ## [1] TRUE
    
    L <- list(1, 2, 3)
    all(sapply(L, identical, L[[1]]))
    ## [1] FALSE
    

    3) Reduce 与之前的解决方案相比,这有点冗长,但由于讨论了Reduce,因此可以这样实现:

    Reduce(function(x, y) x && identical(y, some_list[[1]]), init = TRUE, some_list)
    ## [1] TRUE
    
    Reduce(function(x, y) x && identical(y, L[[1]]), init = TRUE, L)
    ## [1] FALSE
    

    【讨论】:

    • 这也可以,谢谢。但我确实喜欢 Reduce(all.equal, the_list)) 提供更多关于不匹配的信息。
    • Reduce(all.equal, the_list) 不起作用。试试Reduce(all.equal, list(1, 1, 1))
    • 这真的很奇怪!
    • 意识到Reduce(all.equal, list(1, 1, 1)) 的意思是all.equal(all.equal(1, 1), 1)。内部 all.equal 有意义,但外部 all.equal 根本没有意义,因为它将 all.equal 的输出与数字进行比较。
    • 对——它起作用的唯一原因是因为我的“最小可行示例”有两个元素,所以没有外部all.equal
    【解决方案2】:

    这个呢:

    identical(unlist(some_list), unlist(some_other_list))
    

    【讨论】:

    • 感谢您的回答,但我不是要测试两个列表的相等性,而是给定列表中的元素。
    猜你喜欢
    • 1970-01-01
    • 2011-06-12
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多