Рассчитать NA столбцов на основе группирующей переменной с помощью dplyr - PullRequest
3 голосов
/ 16 апреля 2019

Мне не удалось найти подобного вопроса, хотя я сомневаюсь, что он не был опубликован ранее.Мой вопрос связан с Рассчитать, используя dplyr, процент NA'S в каждом столбце .


В наборе данных с несколькими наблюдениями на одного субъекта полезно не только рассчитать общее количествоколичество пропущенных записей данных (т.е. общее количество NA на столбец), но также сколько субъектов имеют пропущенные данные какого-либо рода.

Например, в наборе данных db (см. ниже) item_1 отсутствует для 2 предметов, а item_2 отсутствует для 1 предмета.

Редактировать 1: Что меня интересует, так это то, сколько предметов имеют (любой) пропущенное значение навещь.Даже если в item_2 есть два пропущенных наблюдения для субъекта № 1, его следует считать равным 1, поскольку это все тот же субъект.

library("dplyr")

db <- data.frame(
  subject = c(1, 1, 1, 2),
  item_1 = c(NA, 2, 3, NA),
  item_2 = c(1, NA, NA, 4)
)
db
#>   subject item_1 item_2
#> 1       1     NA      1
#> 2       1      2     NA
#> 3       1      3     NA
#> 4       2     NA      4

До сих пор я подходил к cbind все отдельные вычисления в одном новом data.frame, но это быстро становится беспорядочным (с большим количеством столбцов) и, конечно, плохо кодируется.

Edit 1 : Тем не менее, это показываеттребуемые значения, так как item_1 отсутствует для двух предметов (1 и 2), а item_2 отсутствует только для 1 предмета (субъект 2).

cbind(
  db %>%
    filter(is.na(item_1)) %>%
    summarise(na_item_1 = n_distinct(subject)),
  db %>%
    filter(is.na(item_2)) %>%
    summarise(na_item_2 = n_distinct(subject))
)
#>   na_item_1 na_item_2
#> 1         2         1

Вопрос : есть ли в dplyr подход для расчета этого?

В идеале, я также хотел бы добавить долю пропусков где-то (как в примере ниже):

data.frame(
  type = c("n", "proportion"),
  na_item_1 = c(2, 1.0),
  na_item_2 = c(1, 0.5)
)
#>         type na_item_1 na_item_2
#> 1          n       2.0       1.0
#> 2 proportion       1.0       0.5

Создано в 2019-04-16 пакетом Представить (v0.2.1)

Заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 16 апреля 2019

Другая dplyr версия сначала group_by subject и выясняет группу, которая имеет значение any NA, затем столбец group_by и вычисляет общее значение NA s для nи разделите его на общие уникальные значения subject, чтобы получить prop.

library(dplyr)
library(tidyr)

db %>%
  group_by(subject) %>%
  summarise_all(~any(is.na(.))) %>%
  ungroup() %>%
  select(-subject) %>%
  gather() %>%
  group_by(key) %>%
  summarise(n = sum(value), 
            prop = n/n_distinct(db$subject))

#   key       n  prop
#   <chr>  <int> <dbl>
#1 item_1     2   1  
#2 item_2     1   0.5
1 голос
/ 16 апреля 2019

Другая tidyverse возможность оценить количество НС на предмет и на ИД может быть:

db %>%
 gather(var, val, -subject) %>%
 group_by(var, subject) %>%
 summarise(val = sum(is.na(val))) %>%
 spread(var, val)

  subject item_1 item_2
    <dbl>  <int>  <int>
1       1      1      2
2       2      1      0

Или, если вы хотите, чтобы общее количество NA и доля NA на ID:

db %>%
 gather(var, val, -subject) %>%
 group_by(subject) %>%
 summarise(count = sum(is.na(val)),
           proportion = sum(is.na(val))/n())

  subject count proportion
    <dbl> <int>      <dbl>
1       1     3        0.5
2       2     1        0.5

Или, если вы хотите, чтобы количество и доля НС только для каждого предмета:

bind_rows(db %>%
 select(-subject) %>%
 gather(var, val) %>%
 group_by(var) %>%
 summarise(val = sum(is.na(val))) %>%
 spread(var, val) %>%
 mutate(type = "count"),
 db %>%
 select(-subject) %>%
 gather(var, val) %>%
 group_by(var) %>%
 summarise(val = sum(is.na(val))/n()) %>%
 spread(var, val) %>%
 mutate(type = "proportion"))

  item_1 item_2 type      
   <dbl>  <dbl> <chr>     
1    2      2   count     
2    0.5    0.5 proportion

Или, если вы хотите, чтобы количество и доля уникальных предметов с NA на единицу:

bind_rows(db %>%
 gather(var, val, -subject) %>%
 filter(is.na(val)) %>%
 group_by(var) %>%
 summarise(val = n_distinct(subject)) %>%
 spread(var, val) %>%
 mutate(type = "count"),
 db %>%
 gather(var, val, -subject) %>%
 group_by(var) %>%
 mutate(n = n_distinct(subject)) %>%
 filter(is.na(val)) %>%
 group_by(var) %>%
 summarise(val = first(n_distinct(subject)/n)) %>%
 spread(var, val) %>%
 mutate(type = "proportion"))

  item_1 item_2 type      
   <dbl>  <dbl> <chr>     
1      2    1   count     
2      1    0.5 proportion
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...