【问题标题】:R - Compare vector of objects using ReduceR - 使用 Reduce 比较对象的向量
【发布时间】:2021-11-25 13:52:57
【问题描述】:

我正在尝试使用 Reduce 比较对象的向量 a

  • all.equal 不起作用
  • == 适用于数字,但不足以用于对象。

我更喜欢不使用现有包但仅使用 R 核心功能的解决方案

示例(简化以使用数字向量代替对象):

test <- c(1,1,1,1,1)

Reduce("==",test)

[1] TRUE

我不明白为什么 == 有效而 all.equal 无效

Reduce(all.equal,test)

[1] "Modes: character, numeric"              
[2] "Lengths: 3, 1"                          
[3] "target is character, current is numeric"

最后一句话:

不是重复的。我对比较对象而不是数值

的解决方案感兴趣

数值向量元素的比较:查看stackoverflow上的现有解决方案 Test for equality among all elements of a single numeric vector

【问题讨论】:

  • == 的问题是1 == TRUE eval 为TRUE,但all.equal(1, TRUE) 没有。如果您首先运行Reduce(all.equal, test),它将运行 all.equal(1, 1),这是 TRUE;其次,all.equal(1, TRUE),产生一个字符,以此类推。查看此代码了解更多详情:Reduce(all.equal, test, accumulate = TRUE).
  • 您的c(1,1,1) 示例之所以有效,是因为1 == TRUE

标签: r object compare reduce


【解决方案1】:

您可以在sapply 中尝试identical,并将每个元素与第一个元素进行比较。

x <- list(list(1), list(1))
all(sapply(x[-1], identical, x[[1]]))
#[1] TRUE

x <- list(list(1), list(2))
all(sapply(x[-1], identical, x[[1]]))
#[1] FALSE

【讨论】:

  • 对于大型对象列表,此解决方案比 danloos 解决方案快 20 倍以上。因此这是公认的答案
【解决方案2】:

如果列表中元素的所有成对比较都相同,则返回 TRUE 的函数:

all_pairs_equal <- function(elements) {
    all(mapply(function(x, y) identical(elements[x], elements[y]), 1, seq(1, length(elements))))
}

all_pairs_equal(list(iris, iris, iris))
#> [1] TRUE
all_pairs_equal(list(1, 1, 1))
#> [1] TRUE
all_pairs_equal(list(iris, iris, 2))
#> [1] FALSE

reprex package (v2.0.1) 于 2021-10-05 创建

【讨论】:

  • 我认为没有必要相互比较。如果所有都相等,则必须足以测试所有都等于第一个。
  • 没错,我修改了答案
  • 现在和all(sapply(x, identical, x[[1]]))差别不大
  • 是的,但是我们可以从第二个元素开始,因为引用元素总是与自身相同
  • 是的,但是如果有第二个元素,则需要测试只有一个元素的情况......
猜你喜欢
  • 2022-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多