【问题标题】:Filter with map function in R在 R 中使用 map 函数进行过滤
【发布时间】:2021-09-21 00:46:47
【问题描述】:

我正在尝试过滤数据框的多列 (15)。具体来说,我想使用 Q3 + IQR1.5 和 Q1 - IQR1.5 方法删除异常值。

玩具示例:

library(tidyverse)
aa <- c(2,3,4,3,2,2,1,6,5,4,3,1,15)
bb <- c(0.2,20,30,40,30,20,20,10,30,40,30,10,10)
cc <- c(-9,2,3,4,3,2,2,1,5,4,3,1,25)

df <- tibble(aa,bb,cc)

我试过没有成功:

i <- NULL
for(i in 1:ncol(fat)){
   po <- fat %>% 
     filter(.[[i]] >= (quantile(.[[i]], .25) - IQR(.[[i]]) * 1.5))
   
   po <- fat %>% 
     filter(.[[i]] <= (quantile(.[[i]], .75) + IQR(.[[i]]) * 1.5))
}

我可以使用过滤器和地图功能来做到这一点吗?以及如何?

非常感谢 GS

【问题讨论】:

    标签: r dataframe filter purrr tibble


    【解决方案1】:

    我们可以使用filterif_all/across

    library(dplyr)
    df %>%
        filter(if_all(where(is.numeric), ~ (.>= (quantile(., .25) - IQR(.) * 1.5 )) &
               (.<= (quantile(., .75) + IQR(.) * 1.5 ))))
    

    【讨论】:

    • 哇!它有效,我快疯了......非常感谢。还有两个问题, ~ 那里在做什么,如果所有变量都是数字的(因为它是这种情况),我可以省略 where(is.numeric) 吗?
    • @gus079 关于where(is.numeric) 它正在选择数字列。在您的数据中,所有列都是数字。因此,您可以使用它或 everything() 也可以使用,或者如果您选择了列,请使用 across(1:5, 即 1 到 5
    • 谢谢,非常感谢
    【解决方案2】:

    这里有几个使用 sapply/lapply 的基本 R 选项。我们编写了一个自定义函数来检测异常值并将其应用于每一列,并仅选择其中没有异常值的行。

    is_outlier <- function(x) {
      x <= (quantile(x, .25) - IQR(x) * 1.5) | x >= (quantile(x, .75) + IQR(x) * 1.5)
    } 
    
    df[!Reduce(`|`, lapply(df, is_outlier)), ]
    
    #      aa    bb    cc
    #   <dbl> <dbl> <dbl>
    # 1     3    20     2
    # 2     4    30     3
    # 3     3    40     4
    # 4     2    30     3
    # 5     2    20     2
    # 6     1    20     2
    # 7     6    10     1
    # 8     5    30     5
    # 9     4    40     4
    #10     3    30     3
    #11     1    10     1
    

    使用sapply -

    df[rowSums(sapply(df, is_outlier)) == 0, ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-20
      • 2021-11-15
      相关资源
      最近更新 更多