这两条R线为什么不产生相同的输出?

时间:2018-09-27 04:12:18

标签: r stringr

我最近开始愚弄R,而且我一生都无法弄清楚为什么这两段代码不能产生相同的输出:

 data.short[which(str_detect(data.short$name, "Miss")),]
 data.short[which(grep("Miss", data.short$name) > 1),]

根据我对两个函数str_detectgrep的定义,这两行基本上是相同的。仅过滤名称中包含“ Miss”的条目。

第一个代码正是这样做的。但是,第二个代码无法执行任何操作。有人可以解释一下吗?

2 个答案:

答案 0 :(得分:4)

不,这两个代码没有做相同的事情。

tl; dr

这两行代码相似

data.short[which(str_detect(data.short$name, "Miss")),]

data.short[grep("Miss", data.short$name),]

以防万一,如果您有兴趣了解为什么

让我们举一个可复制的示例

x <- c("one", "onetwo", "two", "threeone", "three")

让我们获取其中包含“一个”的元素的索引

  • str_detect

str_detect返回TRUE / FALSE的值,因此,如果我们需要索引,可以将which包裹在其周围

library(stringr)
which(str_detect(x, "one"))
#[1] 1 2 4

这是正确的,因为位置1、2和4的矢量元素中都带有“ 1”。

现在,让我们转到grep

grep("one", x)
#[1] 1 2 4

这已经给出了所需的预期输出。

但是,当您做

grep("one", x) > 1

你基本上在做

c(1, 2, 4) > 1

给出

[1] FALSE  TRUE  TRUE

因为2和4大于1。

现在您将which包裹在其上,这将为您提供TRUE值的索引,在这种情况下为2和3。

which(grep("one", x) > 1)
#[1] 2 3

答案 1 :(得分:3)

# for str_detect
library(stringr) 
# some mock-up data to use
data.short <- data.frame(name = c(rep("Mister", 3), rep("Miss", 3)))

首先,

data.short[which(str_detect(data.short$name, "Miss")),]

返回(按预期):

[1] Miss Miss Miss
Levels: Miss Mister

第二,

data.short[which(grep("Miss", data.short$name) > 1),]

返回:

[1] Mister Mister Mister
Levels: Miss Mister

这是因为以下内容返回

grep("Miss", data.short$name)
[1] 4 5 6

,如果将其设为“大于1”,则会得到:

which(grep("Miss", data.short$name) > 1)
[1] 1 2 3

最终产生索引为1,2,3(最后一次调用的结果)的元素,而不是索引为4,5,6的元素,您可能打算这样做:

data.short[which(grep("Miss", data.short$name) > 1),]
[1] Mister Mister Mister
Levels: Miss Mister

作为旁注:grep有一个参数value,您可以设置返回索引或索引值:

> grep("Miss", data.short$name)
[1] 4 5 6
> grep("Miss", data.short$name, value = TRUE)
[1] "Miss" "Miss" "Miss" 

编辑

分解str_detect会发生什么:

str_detects对于字符串中包含模式的那些条目返回TRUE

str_detect(data.short$name, "Miss")
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE

which返回索引

which(str_detect(data.short$name, "Miss"))
[1] 4 5 6

并将其用作索引,返回您期望的结果

data.short[which(str_detect(data.short$name, "Miss")),]
[1] Miss Miss Miss
Levels: Miss Mister

我希望这会有所帮助。