将列表部分匹配到列表列表

时间:2016-01-05 15:42:17

标签: r list

我对R来说还是一个新手,我很难正确处理这个问题,所以如果这是重复的话我会提前道歉。

我有一个固定长度列表列表,所有列表都有相同的命名成员。这是我的haystack 我有一个名单成员的名单,但有些人遗失了。这是我的needle

如果needle中存在haystack,我想返回一个简单的TRUE / FALSE。

示例:

这应该返回TRUE:needle的所有成员都匹配haystack[[1]],即使它已丢失c

haystack <- list( list(a = 1, b = 2, c = 3), list(a = 4, b = 5, c = 6) )
needle <- list(a = 1, b = 2)
something(needle, haystack)

这应该返回FALSE:needle的值匹配haystack[[1]],但它们的名称不同

haystack <- list( list(a = 1, b = 2, c = 3), list(a = 4, b = 5, c = 6) )
needle <- list(x = 1, y = 2)
something(needle, haystack)

这应该返回FALSE:a = 1b = 5存在于haystack中,但不在同一列表中

haystack <- list( list(a = 1, b = 2, c = 3), list(a = 4, b = 5, c = 6) )
needle <- list(a = 1, b = 5)
something(needle, haystack)

到目前为止我找到的最接近的是lapply(haystack, match, table = needle),但是A)它并不尊重名称匹配而且B)我不确定如何将其结果转换为逻辑

如果有一个可以让您更轻松的图书馆,请随时将其纳入您的答案。

3 个答案:

答案 0 :(得分:3)

这可能有点粗糙,但我认为它可以完成这项工作。我们需要解决的问题是匹配名称和值。一种非常简单的方法是将它们粘贴在一起。

haystack2 <- lapply(haystack,function(x){
  res <- paste0(names(x),x)
  res
})
# > haystack2
# [[1]]
# [1] "a1" "b2" "c3"
# 
# [[2]]
# [1] "a4" "b5" "c6"

needle2 <- paste0(names(needle),needle)
# > needle2
# [1] "a1" "b2"

然后我们可以使用lapply和%in%:

res <- any(sapply(haystack2,function(x) all(needle2 %in% x)))
# > res
# [1] TRUE

在函数中包装很容易,可以选择返回找到针的干草堆的索引。

something <- function(haystack, needle, position=F){
  haystack2 <- lapply(haystack,function(x) paste0(names(x),x))
  needle2 <- paste0(names(needle),needle)
  res <- sapply(haystack2,function(x) all(needle2 %in% x))
  if(position){
    return(which(res))
  } 
  return(any(res))
}

答案 1 :(得分:1)

灵感来自@Heroka的回答:

int fileSize = 64303;
ByteBuffer result = ByteBuffer.allocate(fileSize);
try (GcsInputChannel readChannel = gcs.openReadChannel(new GcsFilename("mybucket", "mygzippedfile.xml"), 0)) {
  readChannel.read(result);
}

我们的想法是any( sapply( haystack, function(h) all( unlist( needle ) == unlist( h[names(needle)] ) ) ) ) 按照h[names(needle)]中名称显示的顺序从h返回值列表。我们将其转换为矢量,丢弃名称但保留顺序。如果向量的needle元素匹配all转换为向量,则此条目表示匹配。

如果needle中的any个列表返回true,我们会返回haystack作为最终结果。

答案 2 :(得分:0)

好吧,当我写这些函数时,这里有很好的答案,比我的好。所以,只是为了做出微小的贡献,这就是我想出来的。

myFunc <- function(haystack, needle, n = length(needle)){
  values <- sapply(haystack, match, table = needle)
  names <- sapply(lapply(haystack,names), match, table = names(needle))
  for(i in 1:ncol((mtx = values * names))) {
    if(sum(!is.na(mtx[,i]))==n) return(TRUE)
  }
  return(FALSE)
}