r удалить выбросы из списка data.frames и создать новый список data.frames?

У меня есть список из 6 в data.frame

Он имеет 3 столбца:

идентификатор, T_C, продажи

T_C - ТЕСТ или КОНТРОЛЬ

Кто-то помог мне здесь, и я научился находить mean() и sd() с помощью цикла, а не делать отдельные операторы.

Теперь моя цель - удалить выбросы из 6 списков и создать список из 6 (после удаления выбросов).

str(dfList) # это список из 6 в data.frames

Я могу получить среднее значение() и sd() каждого списка следующим образом:

list_mean_sd <- lapply(dfList,
                       function(df) 
                        {
                         df %>%
                           group_by(TC_INDICATOR) %>%
                           summarise(mean = mean(NET_SPEND),
                                     sd = sd(NET_SPEND))
                        })

> str(list_mean_sd)
List of 6  (1 obs. of  2 variables:)

Я могу выбрать их по отдельности для среднего или sd:

sapply(list_mean_sd, "[", "mean")
sapply(list_mean_sd, "[", "sd")

В основном, моя цель состоит в том, чтобы определить выбросы и удалить их, создать альтернативный набор или последующий набор.

**outliers are:  mean - 3*sd()  or  mean + 3*sd()

Я сделал это, но с большим количеством ручных шагов, чтобы научиться перебирать эти наборы и тому подобное, заранее спасибо за помощь!


person Ray Kodiak    schedule 22.12.2016    source источник


Ответы (1)


Попробуйте. Сначала я создаю данные, которые я разбиваю на шесть фреймов данных, которые помещаются в список.

set.seed(0)
test_data <- data.frame(id = 1:10000, 
                        T_C = sample(c(TRUE, FALSE), size = 10000, replace = TRUE),
                        Sales = rnorm(n = 10000),
                        grp = sample(c("a", "b", "c", "d", "e", "f"), 
                                     size = 10000, replace = TRUE))

test_split <- split(test_data, test_data$grp)

Затем я использую lapply в этом списке, чтобы определить, что я называю z_scores, которые вычисляются как разница между mean из Sales и каждым отдельным Sales, деленная на sd из Sales. Наконец, мы используем фильтр для них, чтобы извлечь те, которые имеют z_score с абсолютным значением больше 3.

library(dplyr)
outlier_list <- lapply(test_split, 
       function(m) group_by(m, T_C) %>% mutate(z_score = (Sales - mean(Sales)) / sd(Sales)) %>%
         ungroup() %>% filter(abs(z_score) >= 3)
)

> outlier_list
$a
# A tibble: 5 × 5
     id   T_C     Sales    grp   z_score
  <int> <lgl>     <dbl> <fctr>     <dbl>
1   468  TRUE -2.995332      a -3.073314
2  3026  TRUE  3.028495      a  3.075258
3  5188  TRUE -3.097847      a -3.177952
4  7993 FALSE -3.571076      a -3.823983
5  9105  TRUE -3.216710      a -3.299276

$b
# A tibble: 6 × 5
     id   T_C     Sales    grp   z_score
  <int> <lgl>     <dbl> <fctr>     <dbl>
1   264  TRUE  3.003494      b  3.003329
2  2172  TRUE  3.001475      b  3.001326
3  2980 FALSE -3.176356      b -3.222782
4  3366 FALSE  3.009292      b  3.048559
5  7477 FALSE  3.348301      b  3.392265
6  7583  TRUE -3.089758      b -3.040911

$c
# A tibble: 2 × 5
     id   T_C    Sales    grp  z_score
  <int> <lgl>    <dbl> <fctr>    <dbl>
1  8078  TRUE 3.015343      c 3.129923
2  8991 FALSE 3.113526      c 3.058302

$d
# A tibble: 5 × 5
     id   T_C     Sales    grp   z_score
  <int> <lgl>     <dbl> <fctr>     <dbl>
1   544  TRUE  3.289070      d  3.168235
2  3791 FALSE  3.791938      d  3.769810
3  6771 FALSE -3.157741      d -3.166861
4  7864  TRUE  3.164128      d  3.045728
5  9371  TRUE -3.026884      d -3.024655

$e
# A tibble: 6 × 5
     id   T_C     Sales    grp   z_score
  <int> <lgl>     <dbl> <fctr>     <dbl>
1   186 FALSE  3.021541      e  3.046079
2  1211  TRUE  3.414337      e  3.343521
3  1665  TRUE  3.546282      e  3.473614
4  3765 FALSE  3.363641      e  3.391142
5  4172  TRUE  3.348820      e  3.278923
6  7973 FALSE -2.987790      e -3.015284

$f
# A tibble: 6 × 5
     id   T_C     Sales    grp   z_score
  <int> <lgl>     <dbl> <fctr>     <dbl>
1  1089  TRUE -3.195090      f -3.189979
2  2452 FALSE  3.287591      f  3.212317
3  3486 FALSE -3.334942      f -3.367962
4  4198 FALSE -3.102578      f -3.137082
5  8183  TRUE  3.081077      f  3.075324
6  8656  TRUE  3.253873      f  3.247822

Очевидно, это даст вам только выбросы. Если вы хотите оставить только вставки, измените >= 3 на < 3.

Обновлено, чтобы получить тест Уилкокса на вкладышах.

inlier_list <- lapply(test_split, 
                       function(m) group_by(m, T_C) %>% 
                        mutate(z_score = (Sales - mean(Sales)) / sd(Sales)) %>%
                         ungroup() %>% filter(abs(z_score) < 3)
)

Мы просто запускаем lapply в списке вставок, используя параметры, указанные в комментарии ОП.

wilcox_test_res <- lapply(inlier_list, 
                          function(m) wilcox.test(m$Sales ~ m$T_C, 
                                                  mu= mean(m$Sales[m$T_C == TRUE]), 
                                                  conf.level=0.95,
person Nick Criswell    schedule 22.12.2016
comment
Спасибо! Я не буду на работе до вторника, чтобы попробовать это. Для чего нужна группа? Я прошел курс по R, но я обнаружил, что мне действительно нужно использовать его, чтобы получить какую-либо пользу, класс охватывает слишком много за слишком короткое время. - person Ray Kodiak; 23.12.2016
comment
В этом контексте group_by позволяет мне получить mean и sd, агрегированные по столбцу T_C в каждом data.frame. Поскольку я использую mutate после group_by, столбец, который я добавляю с помощью mutate, вычисляется на основе этой группировки. - person Nick Criswell; 23.12.2016
comment
Нет, я имею в виду, вы добавили столбец grp // для чего это? - person Ray Kodiak; 24.12.2016
comment
Это просто фиктивная переменная, которую я создал, чтобы разделить смоделированные данные на шесть наборов. Для этого я использовал столбец «grp». - person Nick Criswell; 24.12.2016
comment
Это отлично сработало, как я могу использовать цикл внутри Wilcox.test, чтобы он просматривал все эти 6 списков за один раз? - person Ray Kodiak; 27.12.2016
comment
это то, что я использую сейчас: wilcox.test(NET_SPEND ~ TC_INDICATOR, mu=means[CONTROL], conf.level=0.95, paired=F, data=lessoutliers_201611) - person Ray Kodiak; 27.12.2016
comment
Я попытался это сделать, но я вообще не знаком с функцией wilcox.text в R. Я только что получил дополнительный список и запустил функцию, которую вы создали на основе этого списка, с помощью lapply. Не уверен, что это то, что вы собираетесь или нет. Лучше всего задать новый вопрос, в котором подробно описывается, как вы пытаетесь использовать этот тест. - person Nick Criswell; 27.12.2016