2

在 R 中,我需要定义一个vctrs具有唯一性约束的子类。uid我可以在这里为这种新的向量类型提出一个最小的代码。

library(vctrs)

new_uid <- function(x) {
  if (anyDuplicated(x) > 0) stop("Duplicated id")
  new_vctr(x,class="uid")
}

uid <- function(length=0) {
  new_uid(0:(length-1))
}

vec_type2.uid.uid <- function(x,y, ...)  uid()
vec_type2.uid.uid <- function(x, to, ...) x

我可以创建那种类型的向量

x <- new_uid(1:10)
y <- new_uid(11:20)

如果我有重复的值,则会产生错误

z <- new_uid(c(1:10,2))
Error in new_uid(c(1:10, 2)) : Duplicated id

串联起作用并产生更长的uid向量

vec_c(x,y)
<uid[20]>
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

但如果它创建重复项,则不会断言约束,因此不会引发错误。

vec_c(x,x)
<uid[20]>
 [1]  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5  6  7  8  9 10

正如@Rui-Barradas 建议的那样,base::c可以专门化,

c.uid <- function(...){
  x <- unlist(list(...))
  #x <- unique(x)
  new_uid(x)
}

c(x, x)
# Error in new_uid(x) : Duplicated id 

但这不会影响...vctrs::vec_c()使用的功能tibble

我可以定义一些东西来强制在使用连接后断言唯一性约束vec_c吗?

一切顺利,

4

2 回答 2

2

我不确定以下是否是您想要的,我对 vctrs 课程的经验(非常)少。

c.uid <- function(...){
  x <- unlist(list(...))
  #x <- unique(x)
  new_uid(x)
}

c(x, x)
# Error in new_uid(x) : Duplicated id 
于 2021-04-09T18:11:48.047 回答
0

在再次查看vctrs小插图S3 向量后,我测试了一个可行的解决方案。

它需要在传递给通常默认的vec_restore.uid方法之前定义一个断言唯一性的方法:NextMethod

vec_restore.uid <- function(x, to, ...) {
  if (anyDuplicated(na.omit(x)) > 0)
    stop("Duplicated id")
  NextMethod()
}

之后我们得到正确的行为

vec_c(x,x)
Error in vec_restore.uid(x = x, to = to, n = n) : Duplicated id

和同样的

c(x,x)
Error in vec_restore.uid(x = x, to = to, n = n) : Duplicated id

尽管

c(x,y)
<uid[20]>
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20

继续提供正确答案。

谢谢您的帮助。

于 2021-04-15T08:08:49.693 回答