library(dplyr)
library(stringr)
mtcars["names"]<- rownames(mtcars)mtcars["names"]包括"Porsche 914-2"和"Lotus Europa"。很自然,我
> str_detect("Porsche 914-2", "Lotus")
[1] FALSE
> str_detect("Lotus Europa", "Lotus")
[1] TRUE正如我所期望的,我可以更一般地使用函数str_detect(names, "Lotus")来过滤mtcars。
> filter(mtcars, str_detect(names, "Lotus"))
mpg cyl disp hp drat wt qsec vs am gear carb names
1 30.4 4 95.1 113 3.77 1.513 16.9 1 1 5 2 Lotus Europa就像预期的一样,我也得到了
> any(str_detect("Pontiac Firebird", as.character(0:9)))
[1] FALSE
> any(str_detect("Fiat X1-9", as.character(0:9)))
[1] TRUE更普遍地说,any(str_detect(*ANY ELEMENT OF mtcars["names"]*, as.character(0:9)))总是产生预期的结果。所以我希望能够使用第二个函数来过滤mtcars。然而,我得到:
> filter(mtcars, any(str_detect(names, as.character(0:9))))
mpg cyl disp hp drat wt qsec vs am gear carb names
1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4
2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 Mazda RX4 Wag
3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 Datsun 710
4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 Hornet 4 Drive
5 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 Hornet Sportabout
6 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 Valiant
7 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 Duster 360
8 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 Merc 240D
9 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 Merc 230
10 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 Merc 280
11 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 Merc 280C
12 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 Merc 450SE
13 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 Merc 450SL
14 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 Merc 450SLC
15 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4 Cadillac Fleetwood
16 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4 Lincoln Continental
17 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4 Chrysler Imperial
18 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 Fiat 128
19 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 Honda Civic
20 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 Toyota Corolla
21 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1 Toyota Corona
22 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2 Dodge Challenger
23 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2 AMC Javelin
24 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4 Camaro Z28
25 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2 Pontiac Firebird
26 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 Fiat X1-9
27 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2 Porsche 914-2
28 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 Lotus Europa
29 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4 Ford Pantera L
30 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6 Ferrari Dino
31 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8 Maserati Bora
32 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2 Volvo 142E
Warning message:
In stri_detect_regex(string, pattern, opts_regex = opts(pattern)) :
longer object length is not a multiple of shorter object length我既没有预料到这一警告,也没有预料到没有编号的名字仍然存在于数据集中,这意味着有些事情不像预期的那样。
我从dplyr获得了与其他函数类似的行为,比如mutate:基于str_detect的第一个逻辑条件只能按预期工作,而第二个逻辑条件以any(str_detect(开头则不起作用。
有人能解释为什么第二种情况不起作用吗?列的名称是否限制在生成filter逻辑(或为mutate生成新数据)的函数中?
发布于 2019-06-05 13:32:43
as.character(0:9)是长度为10的向量。当您检查长度为1的向量(单个字符串)时,然后在any中包装,就可以得到想要的东西。但是当你开始比较长度32的向量和长度10的向量时,你就会遇到问题。与其用作字符,不如尝试一下regex?filter(mtcars, str_detect(names, "[0-9]"))
发布于 2019-06-05 13:30:04
问题是as.character(0:9)是长度为10的向量。
length(as.character(0:9))
#[1] 10str_detect在string和pattern上是矢量化的,所以当您这样做时
filter(mtcars, str_detect(names, as.character(0:9)))names的前10个值分别与0:9匹配,其余的值再与0:9一起循环,因此您将得到一个警告
较长的对象长度不是较短对象长度的倍数。
你可能在尝试的是
filter(mtcars, str_detect(names, paste0(as.character(0:9), collapse = "|")))
# mpg cyl disp hp drat wt qsec vs am gear carb names
#1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 Mazda RX4
#2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 Mazda RX4 Wag
#3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 Datsun 710
#4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 Hornet 4 Drive
#5 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 Duster 360
#6 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 Merc 240D
#7 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 Merc 230
#8 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 Merc 280
#9 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 Merc 280C
#10 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 Merc 450SE
#11 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 Merc 450SL
#12 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 Merc 450SLC
#13 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 Fiat 128
#14 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4 Camaro Z28
#15 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 Fiat X1-9
#16 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2 Porsche 914-2
#17 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2 Volvo 142E哪里
paste0(as.character(0:9), collapse = "|") #gives
#[1] "0|1|2|3|4|5|6|7|8|9",它是长度为1的字符串,并且在所有名称中搜索相同的模式。
https://stackoverflow.com/questions/56461322
复制相似问题