gpt4 book ai didi

r - 泛化R%in%运算符以匹配元组

转载 作者:行者123 更新时间:2023-12-04 08:25:31 27 4
gpt4 key购买 nike

前几天,我花了一段时间寻找一种检查R中某些行向量中是否包含行向量的方法。基本上,我想归纳%in%运算符以匹配元组而不是向量中的每个条目。例如,我想要:

row.vec = c("A", 3)
row.vec
# [1] "A" "3"

data.set = rbind(c("A",1),c("B",3),c("C",2))
data.set
# [,1] [,2]
# [1,] "A" "1"
# [2,] "B" "3"
# [3,] "C" "2"

row.vec %tuple.in% data.set
# [1] FALSE

对于我的虚构运算符 %tuple.in%,因为行向量 c("A",3)不是data.set中的行向量。使用 %in%运算符可得出:
row.vec %in% data.set
# [1] TRUE TRUE

因为“A”和3在 data.set中,这不是我想要的。

我有两个问题。首先,对此是否有好的解决方案?

其次,由于我找不到它们(即使它们存在),因此我尝试编写自己的函数来做到这一点。它适用于行向量的输入矩阵,但是我想知道是否有专家提出了改进建议:
is.tuple.in <- function(matrix1, matrix2){

# Apply rbind() so that matrix1 has columns even if it is a row vector.
matrix1 = rbind(matrix1)

if(ncol(matrix1) != ncol(matrix2)){
stop("Matrices must have the same number of columns.") }

# Now check for the first row and handle other rows recursively
row.vec = matrix1[1,]
tuple.found = FALSE
for(i in 1:nrow(matrix2)){
# If we find a match, then this row exists in matrix 2 and we can break the loop
if(all(row.vec == matrix2[i,])){
tuple.found = TRUE
break
}
}

# If there are more rows to be checked, use a recursive call
if(nrow(matrix1) > 1){
return(c(tuple.found, is.tuple.in(matrix1[2:nrow(matrix1),],matrix2)))
} else {
return(tuple.found)
}
}

我看到了一些我不确定如何解决的问题。首先,我希望在函数开始时弄清楚基本情况。我之所以无法做到这一点,是因为我在递归调用中传递了 matrix1[2:nrow(matrix1),],如果 matrix1包含一行,则会产生错误。因此,我没有遇到 matrix1为空的情况,而是在最后有一个if条件来确定是否需要更多的迭代。

其次,我认为一开始对 rbind()的使用很草率,但是当 matrix1减少到一行时,我需要它。在不使用 rbind()的情况下, ncol(matrix1)在1行的情况下产生了错误。我认为我的麻烦在于缺乏对R数据类型的了解。

任何帮助,将不胜感激。

最佳答案

我想知道您是否使这一过程变得比实际复杂。例如,

set.seed(1618)
vec <- c(1,3)
mat <- matrix(rpois(1000,3), ncol = 2)
rownames(mat) <- 1:nrow(mat)


mat[sapply(1:nrow(mat), function(x) all(vec %in% mat[x, ])), ]

# gives me this
# [,1] [,2]
# 6 3 1
# 38 3 1
# 39 3 1
# 85 1 3
# 88 1 3
# 89 1 3
# 95 3 1
# 113 1 3
# ...

如果您在意订单,可以进一步分割该子集
或者您可以稍微修改该功能:
mat[sapply(1:nrow(mat), function(x) 
all(paste(vec, collapse = '') %in% paste(mat[x, ], collapse = ''))), ]

# [,1] [,2]
# 85 1 3
# 88 1 3
# 89 1 3
# 113 1 3
# 133 1 3
# 139 1 3
# 187 1 3
# ...

另一个带有更长向量的例子
set.seed(1618)
vec <- c(1,4,5,2)
mat <- matrix(rpois(10000, 3), ncol = 4)
rownames(mat) <- 1:nrow(mat)

mat[sapply(1:nrow(mat), function(x) all(vec %in% mat[x, ])), ]

# [,1] [,2] [,3] [,4]
# 57 2 5 1 4
# 147 1 5 2 4
# 279 1 2 5 4
# 303 1 5 2 4
# 437 1 5 4 2
# 443 1 4 5 2
# 580 5 4 2 1
# ...

我看到一对匹配的:
mat[sapply(1:nrow(mat), function(x) 
all(paste(vec, collapse = '') %in% paste(mat[x, ], collapse = ''))), ]

# [,1] [,2] [,3] [,4]
# 443 1 4 5 2
# 901 1 4 5 2
# 1047 1 4 5 2

但是只有三个

对于您的单行案例:
vec <- c(1,4,5,2)
mat <- matrix(c(1,4,5,2), ncol = 4)
rownames(mat) <- 1:nrow(mat)

mat[sapply(1:nrow(mat), function(x)
all(paste(vec, collapse = '') %in% paste(mat[x, ], collapse = ''))), ]

# [1] 1 4 5 2

这是上面代码的简单功能
is.tuplein <- function(vec, mat, exact = TRUE) {  
rownames(mat) <- 1:nrow(mat)
if (exact)
tmp <- mat[sapply(1:nrow(mat), function(x)
all(paste(vec, collapse = '') %in% paste(mat[x, ], collapse = ''))), ]
else tmp <- mat[sapply(1:nrow(mat), function(x) all(vec %in% mat[x, ])), ]
return(tmp)
}

is.tuplein(vec = vec, mat = mat)
# [1] 1 4 5 2

似乎有效,因此让我们创建自己的 %in%运算符:
`%tuple%` <- function(x, y) is.tuplein(vec = x, mat = y, exact = TRUE)
`%tuple1%` <- function(x, y) is.tuplein(vec = x, mat = y, exact = FALSE)

试一试
set.seed(1618)
c(1,2,3) %tuple% matrix(rpois(1002,3), ncol = 3)

# [,1] [,2] [,3]
# 133 1 2 3
# 190 1 2 3
# 321 1 2 3

set.seed(1618)
c(1,2,3) %tuple1% matrix(rpois(1002,3), ncol = 3)

# [,1] [,2] [,3]
# 48 2 3 1
# 64 2 3 1
# 71 1 3 2
# 73 3 1 2
# 108 3 1 2
# 112 1 3 2
# 133 1 2 3
# 166 2 1 3

关于r - 泛化R%in%运算符以匹配元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22414368/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com