测试某些变量(不同版本)是否出现在数据中

Test whether certain variables (in different versions) appear in data

假设我有一个字符向量(向量 (A)),它在每个元素中包含一个字符串(因此单独的字符串:A1、A2、A3 等。 ).我想将每个字符串与另一个字符串向量(向量 (B))进行比较,以查看是否匹配。

例如,这意味着当向量 A 在其第一个元素中包含字符串 xyz,而向量 B 在任何元素中包含 xyz_blah 时,我将得到 TRUE测试 A-1 是否存在于 B-whatever.

vec_a <- c()
vec_b <- c()

vec_a[1] <- "xyz"
set.seed(2020) ; vec_b[sample(1:100, size = 1)] <- "xyz_blah"

grepl(vec_a, vec_b)

## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [27] FALSE  TRUE

不过我的情况比较复杂。首先,我想在向量 A 中测试多个字符串是否存在于向量 B 中。

vec_a[1] <- "xyz"
vec_a[2] <- "vvtp"
set.seed(2020) 
vec_b[sample(1:100, size = 1)] <- "xyz_blah"
vec_b[sample(1:100, size = 1)] <- "vvtp_blah"

而不是 2 TRUEs,grepl(vec_a, vec_b) returns 都是 FALSE 和错误:

Warning message: In grepl(vec_a, vec_b) : argument 'pattern' has length > 1 and only the first element will be used

其次,有时我知道向量 A 中的字符串在出现在向量 B 中时可能 带有不同的添加(或“版本”)。例如,向量 A 可能包含dog_height and/or dog_weight,向量 B 也可能如此。所以我不仅要指定“词干”字符串,还要指定潜在版本,并测试每个版本是否出现在向量 B 中。它当我的数据可能有 dog_weightweight_dog(但不是两者)时变得更加复杂,所以我知道 dogweight 必须同时存在于一个字符串中矢量 B,但不是确切的模式。

一个连贯的例子

我有一家宠物诊所的数据。

library(tibble)

df <- tribble(~dog_weight, ~dog_height, ~cat_weight, ~cat_height, ~hamster, ~`rabbit~weight`, ~parrot_height, ~`weight-guinea_pig`)

因此:

names(df)

[1] "dog_weight"        "dog_height"        "cat_weight"        "cat_height"        "hamster"           "rabbit~weight"     "parrot_height"     "weight-guinea_pig"

现在假设我想查询我的数据,看看我是否有:

一种方法是指定一个接受动物名称和测量类型的函数,这样一个名为 locate_in_df() 的函数将具有三个参数:

animals <- c("dog", "guinea_pig", "hamster")
measures <- c("weight", "height")

locate_in_df(vector_of_animals = animals,
             type_of_measure = measures,
             dataframe = df)

并且会 return:

  animal     weight height any  
  <chr>      <lgl>  <lgl>  <lgl>
1 dog        TRUE   TRUE   TRUE 
2 guinea_pig TRUE   FALSE  TRUE 
3 hamster    FALSE  FALSE  TRUE 

另一种方法可以指定动物向量和测量类型,并针对 names(df) 进行测试,以便:

vec_of_query <- c("dog, height", "dog, weight", "guinea_pig, weight", "hamster")

然后对 return TRUE TRUE TRUE TRUE 进行某种 grepl() 之类的事情?与第一种方法相比,它的粒度更小,但仍然提供了丰富的信息,它回到了本 post 讨论向量之间匹配字符串的开头。问题是,我不知道如何解决这些想法中的任何一个。知道如何实现吗?

您可以这样实施 locate_in_df

locate_in_df <- function(vector_of_animals, type_of_measure, dataframe) {
   haystack <- names(dataframe)

   vs <- apply(sapply(type_of_measure, function(x) {
     lapply(vector_of_animals, function(y) {
       any(grepl(x, haystack) & grepl(y, haystack))
     })
   }), 2, unlist)
   
   tibble(animals = vector_of_animals, 
          as.data.frame(vs), 
          any = sapply(vector_of_animals, function(x) any(grepl(x, haystack))))
}

这样

locate_in_df(vector_of_animals = animals,
              type_of_measure = measures,
              dataframe = df)

#> # A tibble: 3 x 4
#>   animals    weight height any  
#>   <chr>      <lgl>  <lgl>  <lgl>
#> 1 dog        TRUE   TRUE   TRUE 
#> 2 guinea_pig TRUE   FALSE  TRUE 
#> 3 hamster    FALSE  FALSE  TRUE