Удалить выброс из одной ячейки в R - PullRequest
1 голос
/ 14 июля 2020

Я новичок ie в R, и у меня возникла проблема с удалением некоторых выбросов. У меня есть фрейм данных, который выглядит примерно так:

Item1   Item2   Item3
 4.05    3.9   3.6
 12      3.7   4
 4.01    3.8   4

Мой желаемый результат должен быть примерно таким, как таблица ниже, а именно таблица, в которой удалены выбросы каждого столбца

Item1  Item2  Item3 
4.05    3.9    3.6
NA      3.7    4
4.01    3.8    4 

До сих пор я написал код, который может обнаруживать выбросы, но я застрял в их удалении, так как весь столбец изменяется вместо одного значения.

 find_outlier <- function(log_reaction_time) {
media <- mean(log_reaction_time)
devst <- sd(log_reaction_time)
result <-which(log_reaction_time < media - 2 * devst | log_reaction_time > media + 2 * devst)
log_reaction_time2 <- ifelse (log_reaction_time %in% result, NA, log_reaction_time)
}
apply(log_reaction_time, 2, find_outlier)

Я думаю, проблема связана с тем, что Я применяю функцию к столбцам (2), так как я хочу найти выбросы в столбце, но затем я хочу удалить только соответствующие значения ...

Ответы [ 3 ]

1 голос
/ 14 июля 2020

Мы будем использовать тот же набор данных, чтобы показать это:

#Data
df1 <- structure(list(Item1 = c(4.05, 12, 4.01), Item2 = c(3.9, 3.7, 
3.8), Item3 = c(3.6, 4, 4)), class = "data.frame", row.names = c(NA, 
-3L))

df1
  Item1 Item2 Item3
1  4.05   3.9   3.6
2 12.00   3.7   4.0
3  4.01   3.8   4.0

Теперь функция:

#Function
find_outlier <- function(log_reaction_time) {
  media <- mean(log_reaction_time)
  devst <- sd(log_reaction_time)
  result <-which(log_reaction_time < media - 2 * devst | log_reaction_time > media + 2 * devst)
  log_reaction_time[result] <- NA
  return(log_reaction_time)
}

apply(df1, 2, find_outlier)

     Item1 Item2 Item3
[1,]  4.05   3.9   3.6
[2,] 12.00   3.7   4.0
[3,]  4.01   3.8   4.0

Чтобы выделить, второе значение для Item1 не установлено на NA потому что mean(df1$Item1)=6.69 и sd(df1$Item1)=4.60. Поэтому, когда условие проверяется в интервалах, у вас будут mean(df1$Item1)-2*sd(df1$Item1)=-2.51 и mean(df1$Item1)+2*sd(df1$Item1)=15.89, где 12 не находится в этих пределах. Вам нужно будет определить другие критерии, чтобы присвоить ему NA.

0 голосов
/ 14 июля 2020

Используя dplyr, если df является первым data.frame в вашем сообщении, должно работать следующее:

library(dplyr)
df %>%
  mutate(across(everything(), find_outlier)) -> new_df
0 голосов
/ 14 июля 2020

Не совсем уверен, что вы хотите, но вот решение для любого ...


library(dplyr)

df %>% 
  mutate_all(function(x) ifelse(x < mean(x) - 2 * sd(x) | x > mean(x) + 2 * sd(x) , 
                                NA_real_, 
                                x))
#> # A tibble: 3 x 3
#>   Item1 Item2 Item3
#>   <dbl> <dbl> <dbl>
#> 1  4.05   3.9   3.6
#> 2 12      3.7   4  
#> 3  4.01   3.8   4

media <- mean(as.matrix(df))
devst <- sd(as.matrix(df))

df %>% 
  mutate_all(function(x) ifelse(x < media - 2 * devst | x > media + 2 * devst , 
                                NA_real_, 
                                x))
#> # A tibble: 3 x 3
#>   Item1 Item2 Item3
#>   <dbl> <dbl> <dbl>
#> 1  4.05   3.9   3.6
#> 2 NA      3.7   4  
#> 3  4.01   3.8   4

Ваши данные

library(readr)
df <- read_table("Item1   Item2   Item3
4.05    3.9   3.6
12      3.7   4
4.01    3.8   4")
...