在 R 中,检查字符串是否出现在数据帧行中(在任何列中)


temp = structure(list(name1 = structure(c(2L, 1L, 2L, 1L, 2L), .Label = c("Joe", 
"Mike"), class = "factor"), name2 = c("Nick", "Matt", "Nick", 
"Matt", "Nick"), name3 = c("Matt", "Tom", "Tom", "Steve", "Tom"
)), .Names = c("name1", "name2", "name3"), row.names = c(NA, 
-5L), class = "data.frame")

大家好

我有一个感觉像是 R 的简单编码问题。请参阅下面的数据帧,其代码如上:

name1 name2 name3
1  Mike  Nick  Matt
2   Joe  Matt   Tom
3  Mike  Nick   Tom
4   Joe  Matt Steve
5  Mike  Nick   Tom

我想要一个简单的函数,它返回一个布尔向量,指示特定名称是否出现在该数据帧的行(任何列中(中。例如:

myfunction(Matt) 
# should return
c(TRUE, TRUE, FALSE, TRUE, FALSE).

因为马特出现在第 1、2 和 4 行。感谢任何简单的帮助,谢谢!

这是一个选项。使用apply和匹配(%in%(。

apply(temp, 1, function(x) any(x %in% "Matt")) 
[1]  TRUE  TRUE FALSE  TRUE FALSE

我也提出了自己的解决方案:

rowSums("Matt" == temp) > 0 

似乎可以解决问题

此解决方案使用dplyrpurrr

myFunction <- function(df, name) {
by_row(df, function(x) {name %in% x}, .collate = "cols") %>%
pull(.out)
}
myFunction(temp, "Matt")

by_row将布尔值添加为列。pull将列作为向量返回。

更新by_row功能已从purrr中删除

dplyr或purrr还有其他非常一致和更通用的方法,因此您可以避免与apply()中转换为矩阵相关的类强制带来的问题,for循环的低效率和冗长代码或来自rowSums提案的其他限制。

使用Purrr的地图,Reduce和Stringr的str_detect:

library(purrr)
library(stringr)
temp%>%map(~str_detect(.x,'Matt'))%>%reduce(`|`)

使用dplyr,使用map%>%reducepmap%>%anyrowwise%>%anyif_any

library(purrr)
library(dplyr)
library(stringr)
temp%>%mutate(has_Matt=map(., ~str_detect(.x, 'Matt'))%>%pmap_lgl(any))
#OR
temp%>%rowwise()%>%
mutate(has_Matt=any(str_detect(c_across(everything()), "Matt")))

最简洁的,带有dplyr::if_any:

temp%>%mutate(has_Matt=if_any(everything(), ~.x=="Matt"))

如果要定义一个简化此操作的新函数,可以使用基本 R 创建一个函数:

my_function<-function(dataframe, pattern){
Reduce(`|`, Map(function(x) grepl('Matt', x), dataframe))
}
my_function(temp, "Matt")
[1]  TRUE  TRUE FALSE  TRUE FALSE

最新更新