【问题标题】:How to extract outstanding values from an object returned by waldo::compare()?如何从 waldo::compare() 返回的对象中提取出色的值?
【发布时间】:2020-11-12 14:50:45
【问题描述】:

我正在尝试使用名为 waldo (see at the tidyverse blog too) 的新 R 包,该包旨在比较数据对象以发现差异。 waldo::compare() 函数返回一个对象,根据文档:

具有“waldo_compare”类的字符向量

此功能的主要目的是在控制台中使用,利用着色功能突出显示数据对象之间不相等的突出值。然而,虽然只是在控制台中检查很有用,但我确实想获取这些值并对它们采取行动(将它们从数据中过滤掉,等等)。因此,我想以编程方式提取突出的价值。我不知道怎么做。

示例

  1. 生成长度为 10 的向量:
set.seed(2020)

vec_a <- sample(0:20, size = 10)

## [1]  3 15 13  0 16 11 10 12  6 18
  1. 创建一个重复向量,并将附加值 (4) 添加到第 11 个向量元素中。
vec_b <- vec_a
vec_b[11] <- 4
vec_b <- as.integer(vec_b) 

## [1]  3 15 13  0 16 11 10 12  6 18  4
  1. 使用waldo::compare() 测试两个向量之间的差异
waldo::compare(vec_a, vec_b)

## `old[8:10]`: 12 6 18  
## `new[8:11]`: 12 6 18 4

美妙之处在于它在控制台中突出显示:


但是现在,我如何提取不同的值?

我可以尝试将waldo::compare() 分配给一个对象:

waldo_diff <- waldo::compare(vec_a, vec_b)

然后呢?当我尝试做waldo_diff[[1]] 我得到:

[1] "`old[8:10]`: \033[90m12\033[39m \033[90m6\033[39m \033[90m18\033[39m  \n`new[8:11]`: \033[90m12\033[39m \033[90m6\033[39m \033[90m18\033[39m \033[34m4\033[39m"

对于waldo_diff[[2]],情况更糟:

waldo_diff[3] 中的错误:下标越界

知道如何以编程方式提取出现在“新”向量中但不在“旧”向量中的突出值吗?

【问题讨论】:

    标签: r compare comparison


    【解决方案1】:

    作为免责声明,在您发布之前我对这个包一无所知,因此这远非权威答案,但您无法使用 compare() 函数轻松提取不同的值,因为它返回 ANSI 格式准备好打印的字符串。相反,向量的主力似乎是内部函数ses() 和ses_context(),它们返回两个对象之间差异的索引。不同之处似乎在于ses_context() 将结果拆分为不连续的差异列表。

    waldo:::ses(vec_a, vec_b)
    
    # A tibble: 1 x 5
         x1    x2 t        y1    y2
      <int> <int> <chr> <int> <int>
    1    10    10 a        11    11
    

    结果表明,新向量在位置 11 开始和结束处都有一个加法。

    以下简单函数的范围非常有限,并假设只对新向量中的添加感兴趣:

    new_diff_additions <- function(x, y) {
      res <- waldo:::ses(x, y)
      res <- res[res$t == "a",]  # keep only additions
      if (nrow(res) == 0) {
        return(NULL)
      }  else {
        Map(function(start, end) {
          d <- y[start:end]
          `attributes<-`(d, list(start = start, end = end))
        },
        res[["y1"]], res[["y2"]])
      }
    }
        
    new_diff_additions(vec_a, vec_b)
    
    [[1]]
    [1] 4
    attr(,"start")
    [1] 11
    attr(,"end")
    [1] 11
    

    【讨论】:

      【解决方案2】:

      至少对于比较两个向量的简单情况,你会更好 使用diffobj::ses_dat()(来自 waldo 使用的包 在引擎盖下)直接:

      waldo::compare(1:3, 2:4)
      #> `old`: 1 2 3  
      #> `new`:   2 3 4
      
      diffobj::ses_dat(1:3, 2:4)
      #>       op val id.a id.b
      #> 1 Delete   1    1   NA
      #> 2  Match   2    2   NA
      #> 3  Match   3    3   NA
      #> 4 Insert   4   NA    3
      

      为了完整起见,提取你可以做的补充,例如:

      extract_additions <- function(x, y) {
        ses <- diffobj::ses_dat(x, y)
        y[ses$id.b[ses$op == "Insert"]]
      }
      
      old <- 1:3
      new <- 2:4
      
      extract_additions(old, new)
      #> [1] 4
      

      【讨论】:

      • setdiff() 并不是真正的等价物,因为它会删除重复值,即setdiff(c(1,4,4), c(1,4)) 返回一个空向量。
      • @27ϕ9 好点,我根本没想到。我已经编辑了那部分;我考虑把它留下来说明差异,但最终认为它可能太不同了,甚至无法提及。
      猜你喜欢
      • 2016-10-13
      • 2020-11-03
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-26
      相关资源
      最近更新 更多