有没有一种方法可以在R中运行多个逻辑测试



我有两个Twitter API数据表绑定在一起,我想要一个函数来确定文本是否包含单词f150。如果它找到了,那么它应该返回ford,如果没有,它应该在文本中搜索单词Silverado,如果找到Silverado则应该返回chevy。所有其他都应该为空。

我在网上看到了这个,但它对我不起作用。R中也有像SQL中那样的通配符吗?

`tweet_sentiments <-
tweet_sentiments %>% 
mutate(vehicle = if(text = "f150") {ford}
else_if(text= "silverado"){Chevy})
  1. mutate调用中使用if是合法的,但在这里演示的内容中,这是错误的。由于要对向量进行条件运算,因此应考虑ifelse(基本R(或if_else(在dplyr中(。

    对代码的第一个更改类似于:

    tweet_sentiments %>% 
    mutate(
    vehicle = ifelse(...)
    )
    
  2. text = 'f150'是一个赋值,你需要一个比较,这就是==表示相等。渐进式代码更改:

    tweet_sentiments %>% 
    mutate(
    vehicle = if_else(text == "f150", "Ford",
    if_else(text == "silverado", "Chevy", ...))
    )
    
  3. 您需要一个默认值,如果text既不是"f150"也不是"silverado",则指定该值。选项包括像"unknown"或R惯用NA这样的文字字符串(这意味着实际上"不适用"或"可以是任何东西"(。代码进度:

    tweet_sentiments %>% 
    mutate(
    vehicle = if_else(text == "f150", "Ford",
    if_else(text == "silverado", "Chevy", NA_character_))
    )
    

    (R至少有六种NA,而if_else在保持其yes=no=参数的类为同一类方面相当挑剔。如果您使用ifelse,您本可以将其保持在NA,冒着base::ifelse出现的其他几个问题的风险。它有包袱。(

  4. 您提到了通配符,这表明您可能希望在text中找到"f150"作为子字符串,在这种情况下,我们将需要grepl。代码进度:

    tweet_sentiments %>% 
    mutate(
    vehicle = if_else(grepl("f150", text), "Ford",
    if_else(grepl("silverado", text), "Chevy", NA_character_))
    )
    

    grepl也支持ignore.case=,以防您想考虑不区分大小写的比较。

  5. 最后,回到dplyr——惯用的做事方式。。。每当我看到多个嵌套的ifelse(…(时,我会立即推荐dplyr::case_when。例如,如果你添加另一种或两种汽车类型,它就会变得笨拙:

    tweet_sentiments %>% 
    mutate(
    vehicle = if_else(grepl("f150", text), "Ford",
    if_else(grepl("silverado", text), "Chevy",
    if_else(grepl("RAV4", text), "Toyota", NA_character_)))
    )
    

    但可以清理(凹痕和parens(为:

    tweet_sentiments %>% 
    mutate(
    vehicle = case_when(
    grepl("f150", text) ~"Ford",
    grepl("silverado", text) ~ "Chevy",
    grepl("RAV4", text) ~ "Toyota",
    TRUE ~ NA_character_
    )
    )
    

既然你问起";通配符";,如果您不了解正则表达式,或者不知道regex和glob样式模式之间的区别,那么我建议您查看https://stackoverflow.com/a/22944075/3358272(也许还有?glob2rx,用于将glob样式转换为regex,因为grep*函数只处理regex或固定字符串(。

1(我们可以使用case_when

tweet_sentiments %>%
mutate(vehicle = case_when(text == 'f150' ~ 'ford',
text == 'silverado' ~ 'Chevy'))

2(如果是子字符串,则使用str_detect

library(stringr)
tweet_sentiments %>%
mutate(vehicel = case_when(str_detect(text, 'f150' ~ 'Ford',
str_detect(text, 'silverado') ~ 'Chevy'))

3(另一个选项是%like%

library(data.table)
tweet_sentiments %>%
mutate(vehicle = case_when(text %like% 'f150' ~ 'ford',
text %like% 'silverado' ~ 'Chevy'))

4(另一个选项是rowwiseif/else

tweet_sentiments %>%
rowwise %>%
mutate(vehicle = if(str_detect(text, 'f150')) 'ford' 
else if(str_detect(text, 'silverado')) 'Chevy' else NA_character_) %>%
ungroup

5(或者我们可以使用fuzzy_join

keydat <- tibble(text = c('f150', 'silverado'), value = c('ford', 'Chevy'))
library(fuzzyjoin)
tweet_sentiments %>%
regex_left_join(keydat, by = c('text')) %>%
mutate(vehicle = coalesce(value, vehicle), value = NULL)

最新更新