从 R 中的向量列表中索引特定的数值向量
Index a Particular Numeric Vector From a List of Vectors in R
在 R 中,为了举例,我有一个由等长数字向量组成的列表,其形式类似于:
list <- list(c(1,2,3),c(1,3,2),c(2,1,3))
[[1]]
[1] 1 2 3
[[2]]
[1] 1 3 2
[[3]]
[1] 2 1 3
...
列表中的每个元素都是唯一的。我想获取元素 x <- c(2,1,3)
的索引号,或列表中的任何其他特定数值向量。
我尝试使用 match(x,list)
,它给出了一个充满 NA 的向量,which(list==(c(1,2,3))
,它给了我一个“(列表)对象不能被强制键入 'double' “ 错误。将列表强制为不同类型似乎对 which 函数没有影响。我还尝试了各种 grep* 函数,但这些函数并不 return 精确匹配数字向量。使用 find(c(1,2,3),list)
甚至一些奇特的 sapply
which %in% 类型的函数并没有给我想要的东西。我觉得我有类型问题。有什么建议吗?
--更新--
解决方案摘要
感谢您的回复。这个问题的评论中的方法很干净并且效果很好(通过 akrun)。
> which(paste(list)==deparse(x))
[1] 25
下一个方法不正确
> which(duplicated(c(x, list(y), fromLast = TRUE)))
[1] 49
> y
[1] 1 2 3
这听起来不错,但在下一个块中您可以看到问题
> y<-c(1,3,2)
> which(duplicated(c(list, list(y), fromLast = TRUE)))
[1] 49
更根本的是,我使用的列表中只有 48 个元素。
最后一种方法效果很好(通过 BondedDust),我猜想使用应用函数效率更高:
> which( sapply(list, identical, y ))
[1] 25
尝试:
vapply(list,function(z) all(z==x),TRUE)
#[1] FALSE FALSE TRUE
将上面的行包含在 which
中可以得到列表的索引。
您可以使用 duplicated()
。如果我们将匹配向量添加到原始列表的末尾并设置 fromLast = TRUE
,我们将找到重复项。然后我们可以使用which()
来获取索引。
which(duplicated(c(list, list(c(2, 1, 3)), fromLast = TRUE))
# [1] 3
或者您可以将其添加为第一个元素,然后从结果中减去 1。
which(duplicated(c(list(c(2, 1, 3)), list))) - 1L
# [1] 3
请注意,类型始终与此类比较有关。比较整数和数字时,您需要将双精度数转换为整数,以便 运行 没有问题。例如,1:3
与 c(1, 2, 3)
不是同一类型。
如果传递正确的数据,match
工作正常。
L <- list(c(1,2,3),c(1,3,2),c(2,1,3))
match(list(c(2,1,3)), L)
#[1] 3
请注意,这是通过将列表强制转换为字符来实现的,因此边缘案例将失败 - 向@nicola 致敬:
match(list(1:3),L)
#[1] NA
即使:
1:3 == c(1,2,3)
#[1] TRUE TRUE TRUE
尽管有争议:
identical(1:3,c(1,2,3))
#[1] FALSE
identical(1:3,c(1L,2L,3L))
#[1] TRUE
> L <- list(c(1,2,3),c(1,3,2),c(2,1,3))
> sapply(L, identical, c(2,1,3))
[1] FALSE FALSE TRUE
> which( sapply(L, identical, c(2,1,3)) )
[1] 3
这在测试中的限制会稍微少一些:
> which( sapply(L, function(x,y){all(x==y)}, c(1:3)) )
[1] 1
在 R 中,为了举例,我有一个由等长数字向量组成的列表,其形式类似于:
list <- list(c(1,2,3),c(1,3,2),c(2,1,3))
[[1]]
[1] 1 2 3
[[2]]
[1] 1 3 2
[[3]]
[1] 2 1 3
...
列表中的每个元素都是唯一的。我想获取元素 x <- c(2,1,3)
的索引号,或列表中的任何其他特定数值向量。
我尝试使用 match(x,list)
,它给出了一个充满 NA 的向量,which(list==(c(1,2,3))
,它给了我一个“(列表)对象不能被强制键入 'double' “ 错误。将列表强制为不同类型似乎对 which 函数没有影响。我还尝试了各种 grep* 函数,但这些函数并不 return 精确匹配数字向量。使用 find(c(1,2,3),list)
甚至一些奇特的 sapply
which %in% 类型的函数并没有给我想要的东西。我觉得我有类型问题。有什么建议吗?
--更新-- 解决方案摘要
感谢您的回复。这个问题的评论中的方法很干净并且效果很好(通过 akrun)。
> which(paste(list)==deparse(x))
[1] 25
下一个方法不正确
> which(duplicated(c(x, list(y), fromLast = TRUE)))
[1] 49
> y
[1] 1 2 3
这听起来不错,但在下一个块中您可以看到问题
> y<-c(1,3,2)
> which(duplicated(c(list, list(y), fromLast = TRUE)))
[1] 49
更根本的是,我使用的列表中只有 48 个元素。
最后一种方法效果很好(通过 BondedDust),我猜想使用应用函数效率更高:
> which( sapply(list, identical, y ))
[1] 25
尝试:
vapply(list,function(z) all(z==x),TRUE)
#[1] FALSE FALSE TRUE
将上面的行包含在 which
中可以得到列表的索引。
您可以使用 duplicated()
。如果我们将匹配向量添加到原始列表的末尾并设置 fromLast = TRUE
,我们将找到重复项。然后我们可以使用which()
来获取索引。
which(duplicated(c(list, list(c(2, 1, 3)), fromLast = TRUE))
# [1] 3
或者您可以将其添加为第一个元素,然后从结果中减去 1。
which(duplicated(c(list(c(2, 1, 3)), list))) - 1L
# [1] 3
请注意,类型始终与此类比较有关。比较整数和数字时,您需要将双精度数转换为整数,以便 运行 没有问题。例如,1:3
与 c(1, 2, 3)
不是同一类型。
match
工作正常。
L <- list(c(1,2,3),c(1,3,2),c(2,1,3))
match(list(c(2,1,3)), L)
#[1] 3
请注意,这是通过将列表强制转换为字符来实现的,因此边缘案例将失败 - 向@nicola 致敬:
match(list(1:3),L)
#[1] NA
即使:
1:3 == c(1,2,3)
#[1] TRUE TRUE TRUE
尽管有争议:
identical(1:3,c(1,2,3))
#[1] FALSE
identical(1:3,c(1L,2L,3L))
#[1] TRUE
> L <- list(c(1,2,3),c(1,3,2),c(2,1,3))
> sapply(L, identical, c(2,1,3))
[1] FALSE FALSE TRUE
> which( sapply(L, identical, c(2,1,3)) )
[1] 3
这在测试中的限制会稍微少一些:
> which( sapply(L, function(x,y){all(x==y)}, c(1:3)) )
[1] 1