Эффективное удаление "NA" в проектах повторных измерений с использованием "Tidyverse" - PullRequest
0 голосов
/ 17 февраля 2020

Вопрос не столько в том, как что-то сделать, сколько в том, как сделать это эффективно. В частности, я хотел бы добавить NA s в схему повторных измерений таким образом, чтобы у каждой группы были все полные наблюдения.

В приведенном ниже кадре данных bugs_long один и тот же участник участвует в четырех condition и сообщает свои desire для устранения ошибок в каждом состоянии. Теперь, если бы я хотел провести некоторый анализ повторных измерений с этим набором данных, это обычно не работает в длинном формате, потому что различное количество наблюдений найдено для каждой группы после парного исключения NA с. Таким образом, в окончательном кадре данных должны отсутствовать следующие пять предметов.

# setup
set.seed(123)
library(ipmisc)
library(tidyverse)

# looking at the NAs
dplyr::filter(bugs_long, is.na(desire)) 
#> # A tibble: 5 x 6
#>   subject gender region        education condition desire
#>     <int> <fct>  <fct>         <fct>     <chr>      <dbl>
#> 1       2 Female North America advance   LDHF          NA
#> 2      80 Female North America less      LDHF          NA
#> 3      42 Female North America high      HDLF          NA
#> 4      64 Female Europe        some      HDLF          NA
#> 5      10 Female Other         high      HDHF          NA

Вот текущий окольный способ, которым я взломал это и заставил его работать:

# figuring out the number of levels in the grouping factor
x_n_levels <- nlevels(as.factor(bugs_long$condition))[[1]]

# removing observations that don't have all repeated values
df <-
  bugs_long %>%
  filter(!is.na(condition)) %>%
  group_by(condition) %>%
  mutate(id = dplyr::row_number()) %>%
  ungroup(.) %>%
  filter(!is.na(desire)) %>%
  group_by(id) %>%
  mutate(n = dplyr::n()) %>%
  ungroup(.) %>%
  filter(n == x_n_levels) %>%
  select(-n)

# did this work? yes
df %>%
  group_by(condition) %>%
  count()
#> # A tibble: 4 x 2
#> # Groups:   condition [4]
#>   condition     n
#>   <chr>     <int>
#> 1 HDHF         88
#> 2 HDLF         88
#> 3 LDHF         88
#> 4 LDLF         88

Но я был бы Удивлен, если у tidyverse (dplyr + tidyr) нет более эффективного способа достичь этого, и я был бы очень признателен, если бы кто-то еще лучше рефакторинг этого.

1 Ответ

0 голосов
/ 17 февраля 2020

Вы на самом деле делаете это намного сложнее, чем нужно. Как только вы обнаружите случаи, которые нужно исключить, это всего лишь простая задача удаления строк в ваших данных, которые соответствуют этим темам, то есть защиты от объединения. Некоторые полезные обсуждения здесь и здесь .

set.seed(123)
library(ipmisc)
library(dplyr)

exclude <- filter(bugs_long, is.na(desire))
full_cases <- bugs_long %>%
  anti_join(exclude, by = "subject")

Или выполните фильтрацию и анти-соединение в одном go, аналогично тому, что вы могли бы сделать в SQL:

bugs_long %>%
  anti_join(filter(., is.na(desire)), by = "subject")

В любом случае количество сохраненных проверенных дел:

count(full_cases, condition)
#> # A tibble: 4 x 2
#>   condition     n
#>   <chr>     <int>
#> 1 HDHF         88
#> 2 HDLF         88
#> 3 LDHF         88
#> 4 LDLF         88
...