Несколько аргументов фильтра dplyr

Я хочу отфильтровать несколько ошибок данных в огромном (> 20 000 точек) наборе данных.

Вот предполагаемый набор данных (EDIT: я значительно упростил его):

data<-data.table(age=c(1,1,1,2,2,2,3,3,4,4,4,4,4,4),wt=c(32,12,5,32,80,32,1,0,4,8,1,1,2,50))

В этом гипотетическом примере я хочу исключить значения wt >20 или <6, когда age==1, затем исключить любые значения wt +/- 1 SD от среднего за age 2-3 дня, а затем исключить любые значения wt +/- 2 SD от среднего для age 4.

РЕДАКТИРОВАТЬ Обратите внимание, что я не пытаюсь сгруппировать возраст 2-3 года, чтобы извлечь 1 среднее значение и 1 стандартное отклонение. Вместо этого я хотел бы dplyr извлечь среднее значение и стандартное отклонение для каждого возраста (2 и 3) отдельно и применить одни и те же критерии исключения в этом диапазоне возрастов.

Обычно я знаком с dplyr и думал о том, чтобы решить эту проблему следующим образом (решение, адаптированное из ответа @Suran, которое не сработало так, как нужно):

data_clean<-data%>%filter(
    !(age==1 & wt<6),
    !(age==1 & wt>20),
    !(age==2 & wt >= (mean((data%>%filter(age==2))$wt) +sd((data%>%filter(age==2))$wt))), 
    !(age==2 & wt <= (mean((data%>%filter(age==2))$wt)-sd((data%>%filter(age==2))$wt))),
    !(age==3 & wt >= (mean((data%>%filter(age==3))$wt) +sd((data%>%filter(age==3))$wt))), 
    !(age==3 & wt <= (mean((data%>%filter(age==3))$wt)-sd((data%>%filter(age==3))$wt))),
    !(age==4 & wt >= (mean((data%>%filter(age==4))$wt) +2*sd((data%>%filter(age==4))$wt))), 
    !(age==4 & wt <= (mean((data%>%filter(age==4))$wt)-2*sd((data%>%filter(age==4))$wt)))
        )

Это действительно громоздкое решение, и оно мне не под силу, учитывая, что на самом деле у меня есть 8 различных критериев исключения для разных возрастов. Любые предложения о том, как я могу собрать это вместе?

Обновлено: желаемый окончательный набор данных будет выглядеть так:

     age  wt
      1  12
      2  32
      2  32
      3   1
      3   0
      4   4
      4   8
      4   1
      4   1
      4   2

Вы можете использовать несколько каналов фильтрации в своей последовательности фильтрации. Поэтому просто реализуйте свою последовательность фильтров поэтапно для ясности.

SteveM 11.12.2020 00:21

@SteveM Я обновил свой вопрос, чтобы прояснить ситуацию.

Blundering Ecologist 11.12.2020 19:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
136
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы получить mean() для каждого age, вам нужно сначала group_by(age) и scale() перед выполнением аргументов фильтра.

data_clean <- data
    group_by(age) %>%
    mutate(x = abs(scale(wt)[,1])) %>% #create a new variable that scales the wt, x<=1 means wt is within 1 SD of mean, x<=2 means wt is within 2 SD of mean
    ungroup() %>%
    filter((age==1 & wt %in% c(6:20) | #keep weights >6g and <20g at age==1
        age %in% c(2:3) & x <= 1 | #keep mean wts ± 1 SD for 2-3 days 
        age>=4 & x<=2) %>% #keep mean wts ± 2 SD for >=4 days
     select(-x)

Другие вопросы по теме