我有两个Twitter API数据表绑定在一起,我想要一个函数来确定文本是否包含单词f150。如果它找到了,那么它应该返回ford,如果没有,它应该在文本中搜索单词Silverado,如果找到Silverado则应该返回chevy。所有其他都应该为空。
我在网上看到了这个,但它对我不起作用。R中也有像SQL中那样的通配符吗?
`tweet_sentiments <-
tweet_sentiments %>%
mutate(vehicle = if(text = "f150") {ford}
else_if(text= "silverado"){Chevy})
-
在
mutate
调用中使用if
是合法的,但在这里演示的内容中,这是错误的。由于要对向量进行条件运算,因此应考虑ifelse
(基本R(或if_else
(在dplyr
中(。对代码的第一个更改类似于:
tweet_sentiments %>% mutate( vehicle = ifelse(...) )
-
text = 'f150'
是一个赋值,你需要一个比较,这就是==
表示相等。渐进式代码更改:tweet_sentiments %>% mutate( vehicle = if_else(text == "f150", "Ford", if_else(text == "silverado", "Chevy", ...)) )
-
您需要一个默认值,如果
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
出现的其他几个问题的风险。它有包袱。( -
您提到了通配符,这表明您可能希望在
text
中找到"f150"
作为子字符串,在这种情况下,我们将需要grepl
。代码进度:tweet_sentiments %>% mutate( vehicle = if_else(grepl("f150", text), "Ford", if_else(grepl("silverado", text), "Chevy", NA_character_)) )
grepl
也支持ignore.case=
,以防您想考虑不区分大小写的比较。 -
最后,回到
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(另一个选项是rowwise
和if/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)