我有一个表,称其为df,具有3列,第一个是产品的标题,第二个是产品的说明,第三个是一个单词字符串。我需要做的是在整个表上运行一个操作,创建2个新列(将它们称为“exists_in_title”和“exists_in_description”),它们具有1或0指示第一列或第二列中是否存在第三列。我需要将其简单地做为1:1运算,因此,例如,调用第1行“A”,我需要检查单元格A3是否存在于A1中,并使用该数据创建列
exist_in_title,然后检查A2中是否存在A3,并使用该数据创建一列exist_in_description。然后继续前进到B行,并执行相同的操作。我有成千上万的数据行,因此一次以1的方式执行这些操作是不现实的,为每行编写单独的函数,绝对需要一个函数或方法来一次性遍历表中的每一行。
我玩过grepl,pmatch,str_count,但似乎没有一个能真正满足我的需要。我认为grepl可能是最接近我需要的代码,这是我编写的两行代码的示例,这些行在逻辑上可以实现我希望它们执行的操作,但似乎没有用:
df$exists_in_title <- grepl(df$A3, df$A1)
df$exists_in_description <- grepl(df$A3, df$A2)
但是,当我运行这些命令时,收到以下消息,这使我相信它无法正常工作:“参数'pattern'的长度> 1,并且仅将使用第一个元素”
任何有关如何执行此操作的帮助将不胜感激。谢谢!
最佳答案
grepl
将与mapply
一起使用:
样本数据框:
title <- c('eggs and bacon','sausage biscuit','pancakes')
description <- c('scrambled eggs and thickcut bacon','homemade biscuit with breakfast pattie', 'stack of sourdough pancakes')
keyword <- c('bacon','sausage','sourdough')
df <- data.frame(title, description, keyword, stringsAsFactors=FALSE)
使用
grepl
搜索匹配项:df$exists_in_title <- mapply(grepl, pattern=df$keyword, x=df$title)
df$exists_in_description <- mapply(grepl, pattern=df$keyword, x=df$description)
结果:
title description keyword exists_in_title exists_in_description
1 eggs and bacon scrambled eggs and thickcut bacon bacon TRUE TRUE
2 sausage biscuit homemade biscuit with breakfast pattie sausage TRUE FALSE
3 pancakes stack of sourdough pancakes sourdough FALSE TRUE
更新我
您也可以使用
dplyr
和stringr
做到这一点:library(dplyr)
df %>%
rowwise() %>%
mutate(exists_in_title = grepl(keyword, title),
exists_in_description = grepl(keyword, description))
library(stringr)
df %>%
rowwise() %>%
mutate(exists_in_title = str_detect(title, keyword),
exists_in_description = str_detect(description, keyword))
更新二
Map
也是一个选项,或者使用tidyverse
中的更多选项,另一个选项可以是purrr
和stringr
:library(tidyverse)
df %>%
mutate(exists_in_title = unlist(Map(function(x, y) grepl(x, y), keyword, title))) %>%
mutate(exists_in_description = map2_lgl(description, keyword, str_detect))
关于r - 如何在数据框的其他列中的一列中搜索字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30782065/