Почему эти две строки R не дают одинаковый результат? - PullRequest
0 голосов
/ 27 сентября 2018

Я недавно начал дурачиться с R, и, судя по всему, не могу понять, почему эти два фрагмента кода не выдают одинаковый результат:

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

Из определенийиз двух функций str_detect и grep Я понимаю, что эти две строки по сути одинаковы;отфильтровывать только те записи, которые содержат «Miss» в своих именах.

Первый код делает именно это.Второй код, однако, ничего не делает.Может кто-нибудь объяснить, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018
# 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

Надеюсь, это поможет.

0 голосов
/ 27 сентября 2018

Нет, эти два кода не делают одно и то же.

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 есть «один».

Теперь давайте перейдем к 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
...