【问题标题】:Test whether certain variables (in different versions) appear in data测试某些变量(不同版本)是否出现在数据中
【发布时间】:2021-03-24 07:13:59
【问题描述】:

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

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

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) 返回所有 FALSE 和错误:

警告消息:在 grepl(vec_a, vec_b) 中:参数“模式”有 length > 1 并且只使用第一个元素

其次,有时我知道向量 A 中的字符串可能在出现在向量 B 中时带有不同的添加(或“版本”)。例如,向量 A 可能包含 dog_height 和/或dog_weight,向量B也是如此。所以我不仅要指定“stem”字符串,还要指定潜在版本,并测试每个版本是否出现在向量B中。当我的数据可能有@时,它变得更加复杂987654331@ 或 weight_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() 的函数将具有三个参数:

  • vector_of_animals 其中有c(dog, guinea_pig, hamster);和
  • type_of_measure 可以是 c(height, weight, any)
  • 要检查的数据框
animals <- c("dog", "guinea_pig", "hamster")
measures <- c("weight", "height")

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

并且会返回:

  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")

然后某种grepl() 之类的东西返回TRUE TRUE TRUE TRUE?它会比第一种方法更细化,但仍然提供信息,它回到了这篇文章的开头,讨论了向量之间的匹配字符串。问题是,我不知道如何解决这些想法。知道如何实现吗?

【问题讨论】:

    标签: r string vector string-matching


    【解决方案1】:

    你可以像这样实现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 
    

    【讨论】:

    • 谢谢你,@Allan。只有一件事——haystack &lt;- names(df) 必须是 haystack &lt;- names(dataframe) 才能匹配 locate_in_df 的数据参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多