【问题标题】:r - Find String in Any Elements of a List and Then Use the Name of That List Elementr - 在列表的任何元素中查找字符串,然后使用该列表元素的名称
【发布时间】:2020-02-08 16:42:06
【问题描述】:

我正在尝试查看该字符串是否存在于列表中的任何元素中,然后使用该列表的名称(如果存在)。

目前,我正在使用case_whengrepl,但我想要一种更有效的方式来查看我的named_list,然后使用该名称。


fruit <- c("apple", "banana", "pear")
drinks <- c("beer", "wine", "coffee")
stuff <- c("chair", "couch", "desk")


df <- data.frame(foo = sample(x = c(fruit, drinks, stuff), size = 10, replace = T),
                 x = sample(1:500, size = 10, replace = T))

df

# foo    x
# pear   449
# wine   241
# pear   53
# couch  72
# banana 443
# coffee 172
# desk   126
# desk   183
# desk   7
# banana 73

df %>%
  mutate(category = case_when(grepl(paste0(fruit, collapse = "|"), foo, ignore.case = T) ~ "fruit",
                              grepl(paste0(drinks, collapse = "|"), foo, ignore.case = T) ~ "drinks",
                              grepl(paste0(stuff, collapse = "|"), foo, ignore.case = T) ~ "stuff"))

# foo    x   category
# pear   449 fruit
# wine   241 drinks
# pear   53  fruit
# couch  172 stuff
# banana 443 fruit
# coffee 172 drinks
# desk   126 stuff
# desk   183 stuff
# desk   7   stuff
# banana 73  fruit

# create named list of lists/vectors
named_list <- Hmisc::llist(fruit, drinks, stuff)
named_list

【问题讨论】:

    标签: r list for-loop dplyr


    【解决方案1】:

    你可以这样做:

    gsub("\\d", "", names(sort(unlist(lapply(named_list, lapply, function(x) grep(x, df$foo))))))
    #> [1] "drinks" "stuff"  "fruit"  "drinks" "stuff"  "stuff"  "stuff"  "stuff"  "drinks"
    #> [10] "fruit" 
    

    这通过获取命名列表并检查其每个向量(使用 lapply)来工作。对于每个向量,它再次调用 lapply 到 grep 针对 df$foo 的命名列表向量的每个成员。

    结果是一个嵌套列表,其中每个叶子都是针对特定项目的匹配索引的向量。当您取消列出此嵌套列表时,命名列表的名称与每个元素相关联。这些可以按它们的索引顺序排列,然后是使用的名称。您必须去掉由封闭 gsub 添加到名称中的数字。

    【讨论】:

    • 这似乎行得通!但我不确定它是如何工作的……你能解释一下嵌入式 lapply 吗?
    • 当然,我会用解释更新我的答案@alexb523
    • 这适用于示例,但是当我将其应用于我的实际问题时,我得到以下信息:错误:列category 的长度必须为 77(行数)或一,而不是85. 知道发生了什么吗?我在成功排除故障时遇到了问题。
    • @alexb523 你在用dplyr吗?
    • 是的,我正在尝试使用dplyr 来实现它。当我将它插入示例时它可以工作,但不能插入我的实际代码。 df %&gt;% mutate(category = gsub("\\d", "", names(sort(unlist(lapply(named_list, lapply, function(x) grep(x, foo)))))))
    【解决方案2】:

    这是一个基本的 R 解决方案,使用 name 的属性

    tbl <- `names<-`(unlist(lst <- list(fruit = fruit, drinks = drinks, stuff = stuff)),
                     rep(names(lst),lengths(lst)))
    df$category <- names(tbl)[match(df$foo,tbl)]
    

    示例

    > df
          foo   x category
    1    desk 277    stuff
    2    beer 362   drinks
    3   chair 438    stuff
    4   apple 494    fruit
    5  banana 330    fruit
    6   chair 263    stuff
    7  banana 329    fruit
    8    pear  79    fruit
    9   apple 213    fruit
    10   wine  37   drinks
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-25
      • 2018-07-30
      • 1970-01-01
      相关资源
      最近更新 更多