给定如下数据结构:
set.seed(10)
fruits <- c("apple", "orange", "pineapple")
fruits2 <- data.frame(id = 1:10, fruit1 = sample(fruits, 10, replace = T), fruit2 = sample(fruits, 10, replace = T), fruit3 = sample(fruits, 10, replace = T))
> fruits2
id fruit1 fruit2 fruit3
1 1 orange orange pineapple
2 2 apple orange orange
3 3 orange apple pineapple
4 4 pineapple orange orange
5 5 apple orange orange
6 6 apple orange pineapple
7 7 apple apple pineapple
8 8 apple apple apple
9 9 orange orange pineapple
10 10 orange pineapple orange
我可以轻松测试data.frame 中的任何位置是否与<{1}}的给定字符串完全相同,它将返回一种非常方便的格式。例如:
fruits2 == "mystring"
但是,我真正想做的是搜索模式(例如“apple”)并返回相同的格式。也就是说,我希望能够测试data.frame 中的每个项是否包含(但不一定等于)字符串“apple”并返回相同的逻辑矩阵。在这种情况下,我希望它产生:
fruits2 == "orange"
id fruit1 fruit2 fruit3
[1,] FALSE TRUE TRUE FALSE
[2,] FALSE FALSE TRUE TRUE
[3,] FALSE TRUE FALSE FALSE
[4,] FALSE FALSE TRUE TRUE
[5,] FALSE FALSE TRUE TRUE
[6,] FALSE FALSE TRUE FALSE
[7,] FALSE FALSE FALSE FALSE
[8,] FALSE FALSE FALSE FALSE
[9,] FALSE TRUE TRUE FALSE
[10,] FALSE TRUE FALSE TRUE
有没有简单的方法在R中执行此操作而不指定多个模式(我知道在这种情况下 id fruit1 fruit2 fruit3
[1,] FALSE FALSE FALSE TRUE
[2,] FALSE TRUE FALSE FALSE
[3,] FALSE FALSE TRUE TRUE
[4,] FALSE TRUE FALSE FALSE
[5,] FALSE TRUE FALSE FALSE
[6,] FALSE TRUE FALSE TRUE
[7,] FALSE TRUE TRUE TRUE
[8,] FALSE TRUE TRUE TRUE
[9,] FALSE FALSE FALSE TRUE
[10,] FALSE FALSE TRUE FALSE
会这样做,但在我的真实数据集中枚举所有可能完全匹配的字符串是不可能的)?< / p>
我认为有解决方法,我可以使用fruits2 == "apple" | fruits2 == "pineapple"
编写一个函数来完成它,但我想知道是否有更简单的解决方案。
答案 0 :(得分:5)
在基地R,
> apply(fruits2,2,function(x){grepl("apple",x)})
id fruit1 fruit2 fruit3
[1,] FALSE FALSE FALSE TRUE
[2,] FALSE TRUE FALSE FALSE
[3,] FALSE FALSE TRUE TRUE
[4,] FALSE TRUE FALSE FALSE
[5,] FALSE TRUE FALSE FALSE
[6,] FALSE TRUE FALSE TRUE
[7,] FALSE TRUE TRUE TRUE
[8,] FALSE TRUE TRUE TRUE
[9,] FALSE FALSE FALSE TRUE
[10,] FALSE FALSE TRUE FALSE
n = 10000
fruits2 <- data.frame(id = 1:n, fruit1 = sample(fruits, n, replace = T), fruit2 = sample(fruits, n, replace = T), fruit3 = sample(fruits, n, replace = T))
> system.time(apply(fruits2,2,function(x){grepl("apple",x)}))
user system elapsed
0.016 0.000 0.019
> system.time(colwise(myfun)(fruits2))
user system elapsed
0.016 0.000 0.017
> system.time(sapply(fruits2,function(x) grepl('apple',x)))
user system elapsed
0.032 0.000 0.034
正如@eddi指出的那样,lapply
确实是最快的:
> system.time(do.call("cbind",lapply(colnames(fruits2),function(x) grepl('apple',fruits2[,x]))))
user system elapsed
0.016 0.000 0.016
答案 1 :(得分:3)
Dunno如果你认为这更简单,但你可以使用colwise
包中的plyr
:
myfun <- function(x) grepl('apple', x)
colwise(myfun)(fruits2)
id fruit1 fruit2 fruit3
1 FALSE FALSE FALSE TRUE
2 FALSE TRUE FALSE FALSE
3 FALSE FALSE TRUE TRUE
4 FALSE TRUE FALSE FALSE
5 FALSE TRUE FALSE FALSE
6 FALSE TRUE FALSE TRUE
7 FALSE TRUE TRUE TRUE
8 FALSE TRUE TRUE TRUE
9 FALSE FALSE FALSE TRUE
10 FALSE FALSE TRUE FALSE