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
似乎可以解决问题
此解决方案使用dplyr
和purrr
。
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%>%reduce
、pmap%>%any
、rowwise%>%any
或if_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