通过均值的标准差查找异常值,在大型数据集(6000 多列)中用 NA 替换

Find outliers by Standard Deviation from mean, replace with NA in large dataset (6000+ columns)

我找到了一些与我正在寻找的答案相似的答案,但代码没有用。

我需要用 NA 或 NULL 替换每列的所有异常值(为我们的目的定义为偏离平均值超过 2 SD)。我正在尝试遍历所有列,计算每列的异常值并替换这些值。

披露:我还知道,从统计学上来说,对于移除异常值存在强烈的看法,并且考虑到在这种情况下计算的 SD 包括异常值,因此使用 SD 作为排除它们的措施。这些是我们的统计学家给我的指示,所以我现在正在处理它。

这是我的数据集的一瞥:

data

Group sp.Q13813.SPTN1_HUMAN sp.O14773.TPP1_HUMAN sp.P11137.MTAP2_HUMAN
1 Premutation           10713983468            367492324            2134747097
2 Premutation           10789498495            343303410            2677825476
3 Premutation           11134883489            383589325            2132552280
4 Premutation            9723552595            269965000            2262740921
5 Premutation           11175156282            359864993            1419225650
6 Premutation           10959077349            258095035            3343267633
7 Premutation           10770809133            331554977            2763604046
8 Premutation           11098182537            344384433            2198718886

我已经尝试过包含 scale() 函数的代码,但是当我执行以下函数时,我发现它替换了列平均值 2 SD 以内的值,并且它使我的代码保留了缩放格式.我不太熟悉这个函数,也不确定如何将它恢复到原始数据点,即使它正在替换正确的离群值。

方法尝试#1

# take note of order for column names
data.names_P <- colnames(data)


# scale all numeric columns
data.numeric.Pre <- select_if(data, is.numeric) %>% # subset of numeric columns
  mutate_all(scale)                             # perform scale separately for each column
data.numeric.Pre[data.numeric.Pre > 2] <- 99999 # set values larger than 2 to NA (none in this example)

# combine results with subset data frame of non-numeric columns
data.Pre <- data.frame(select_if(data, function(x) !is.numeric(x)),
                   data.numeric)

# restore columns to original order
data.Pre <- data.Pre[, data.names_P]

方法尝试 #2


FindOutliers <- function(data) {
  upper = (2*sd(data) + mean(data)
  lower = (mean - 2*sd(data))
  result <- which(data < upper | data > lower)
}

我知道第二次尝试不会用 NA 替换数据。

如有任何帮助,我们将不胜感激。

您可以使用 ifelse 函数,这里是一个使用 dplyr 并将 ifelse 函数应用于包含术语 HUMAN:[=15= 的所有列的示例]

library(dplyr)
data %>% mutate_at(.vars = vars(contains("HUMAN")), 
                   .funs= ~ifelse(abs(.)>mean(.)+2*sd(.), NA, .))

我们可以使用您第二次尝试的函数将数据替换为 NA

FindOutliers <- function(data) {
   mean_data <- mean(data, na.rm = TRUE)
   sd_data <- sd(data, na.rm = TRUE)
   upper = 2*sd_data + mean_data
   lower = mean_data - 2*sd_data
   replace(data, data > upper | data < lower, NA)
}

library(dplyr)
data %>%  mutate_if(is.numeric, FindOutliers)
#Tested it via
#mtcars %>%  mutate_if(is.numeric, FindOutliers)