如何过滤R中的一系列数字?

Pau*_*him 9 filtering r

假设我有数据帧Mydata,如下所示:

Mydata <- data.frame(x = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
                     y = c(20, 30, 45, 54, 65, 78, 97, 102, 123, 156))
Run Code Online (Sandbox Code Playgroud)

我想过滤此数据框并创建另一个数据框,以便只显示x介于3和之间的值7及其对应的y值.我尝试了以下方法:

new_frame <- Mydata %>% filter(x == (3:7))
Run Code Online (Sandbox Code Playgroud)

这没用.那我怎么过滤指定范围?

在此先感谢您的帮助

MHa*_*mer 7

使用 %in%

library(dplyr)
new_frame<- Mydata%>% filter(x %in% (3:7))
new_frame
#   x  y
# 1 3 45
# 2 4 54
# 3 5 65
# 4 6 78
# 5 7 97
Run Code Online (Sandbox Code Playgroud)


Ann*_*nna 7

很多好的 dplyr 解决方案,例如过滤或硬编码一些答案中已经存在的上限和下限:

MydataTable%>% filter(between(x, 3, 70))
Mydata %>% filter(x %in% 3:7)
Mydata %>% filter(x>=3&x<=7)
Run Code Online (Sandbox Code Playgroud)

您还可以使用 data.table,这对于大型数据集来说非常快。 inrangebetween为此目的相同地工作

library(data.table)
MydataTable <- data.table(x = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
                          y = c(20, 30, 45, 54, 65, 78, 97, 102, 123, 156))
MydataTable[x %inrange% c(3,7)]
MydataTable[x %between% c(3,7)]
Run Code Online (Sandbox Code Playgroud)

这种方法的一个好处(除了 data.table 的速度之外)是您只需要指定最小和最大范围 - 您不需要创建一个数组来对过滤器进行子集化。

这些方法的时间比较:

> df <- data.frame(x = sample(1:10, 10000000, replace = T),
+                      y = sample(1:10, 10000000, replace = T))
> system.time({ df %>% filter(between(x, 3, 7)) })
   user  system elapsed 
   0.18    0.05    0.14 
> system.time({ df %>% filter(x %in% 3:7) })
       user  system elapsed 
       0.19    0.06    0.29 
> system.time({ df %>% filter(x>=3&x<=7)  })
   user  system elapsed 
   0.17    0.09    0.26 

> dt <- data.table(df)
> system.time( {dt[x %inrange% c(3,7)] })
   user  system elapsed 
   0.13    0.07    0.21 
> system.time( {dt[x %between% c(3,7)] })
   user  system elapsed 
   0.18    0.05    0.13
Run Code Online (Sandbox Code Playgroud)

  • `dplyr::between` 也有效,`between(x, 3, 7)`。由于您提到了不同的方法,因此区分它们会很有用。`%in%`、`%between%` 和 `%inrange%` 都有不同的用途,在这种情况下它们只是碰巧重叠。并且 `{dt[x %in% 3:7]}` 也应该在基准测试中进行比较。(并且单次运行的基准测试可能变化很大,出于计时目的,我建议使用 `microbenchmark::microbenchmark()`。) (3认同)

Moo*_*per 5

还有旧的base::subset

subset(Mydata, x >= 3 & x <= 7)
subset(Mydata, x %in% 3:7)
Run Code Online (Sandbox Code Playgroud)