Функция na.rm не работает, если используется более 1 группы в R - PullRequest
0 голосов
/ 08 сентября 2018

В этом посте выберите группу перед определенными наблюдениями, разделенными группировкой var в R с контролем NA , при использовании одной группы add na.rm=T работает. Но новые данные, где три группы

data=structure(list(add = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "x", class = "factor"), 
    x1 = c(0L, 2L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 
    1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 3L, 0L, 0L, 
    0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L), add1 = c(514L, 514L, 
    514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 
    514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 
    514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 
    514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 
    514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L, 514L
    ), group = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("female", 
    "male"), class = "factor"), add2 = c(2018L, 2018L, 2018L, 
    2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 
    2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 
    2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 
    2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 
    2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 2018L, 
    2018L, 2018L, 2018L, 2018L)), .Names = c("add", "x1", "add1", 
"group", "add2"), class = "data.frame", row.names = c(NA, -52L
))

поэтому, когда я запускаю код

library(tidyverse)
library( data.table)
data %>%  
  group_by(add,add1,add2) %>%                                          
  mutate(group2 = rleid(group)) %>% 
  group_by(add,add1,add2, group, group2) %>%
  mutate(MEAN = mean(x1[group=="male" & group2==1], na.rm = T),      ## extra code here ##    
         Q25 = quantile(x1[group=="male" & group2==1], 0.25, na.rm = T)) %>%  ## extra code here ##
  group_by(add,add1,add2) %>%                                           
  mutate(x1 = ifelse(group=="male" & group2==3 & x1 > unique(Q25[!is.na(Q25)]), unique(MEAN[!is.na(MEAN)]), x1))%>%
  ungroup() %>%
  select(-group2) %>%
  data.frame()

я получаю ошибку

Error in mutate_impl(.data, dots) : 
  Column `x1` must be length 24 (the group size) or one, not 0

PS. Я просто привел один пример, чтобы дать структуру данных, потому что есть 1000 групп. Я не могу найти группу из которого происходит ошибка

как исправить эту ошибку.

1 Ответ

0 голосов
/ 09 сентября 2018

Если я правильно понимаю, ошибка вызвана первой мужской группой, где все x1 равны NA в первом разделе (group == 1L).

ИМХО, более чистый подход заключается в том, чтобы сначала вычислить статистику для всех групп, как это было предложено здесь , и использовать неэквивалентное объединение, чтобы обновить затронутые строки во второй группе мужчин, как предложено, здесь .

library( data.table)
grp_stats <- setDT(data)[, group2 :=rleid(group), by = .(add, add1, add2)][
  group2 == 1L & group == "male", 
  .(group2 = 3L, mean = mean(x1, na.rm = TRUE), q25 = quantile(x1, 0.25, na.rm = TRUE)), 
  by = .(add, add1, add2)] 
grp_stats 
   add add1 add2 group2 mean  q25
1:   x  514 2018      3  1.5 1.25
2:   y  515 2018      3  NaN   NA
3:   z  516 2018      3  2.0 2.00

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

Однако для последующего объединения мы можем оставить их, поскольку они не будут иметь никакого влияния.

Столбец group2 с постоянным значением 3 уже добавлен в статистику группы для упрощения последующих update in a non-equi join:

data[, x1 := as.numeric(x1)][
  grp_stats, on = .(group2, add, add1, add2, x1 > q25), x1 := mean][]
data
    add  x1 add1  group add2 group2
 1:   x 1.0  514   male 2018      1
 2:   x 2.0  514   male 2018      1
 3:   x  NA  514 female 2018      2
 4:   x  NA  514 female 2018      2
 5:   x 1.5  514   male 2018      3
 6:   x 1.0  514   male 2018      3
 7:   y  NA  515   male 2018      1
 8:   y  NA  515   male 2018      1
 9:   y  NA  515 female 2018      2
10:   y  NA  515 female 2018      2
11:   y 7.0  515   male 2018      3
12:   y 1.0  515   male 2018      3
13:   z 2.0  516   male 2018      1
14:   z  NA  516   male 2018      1
15:   z  NA  516 female 2018      2
16:   z  NA  516 female 2018      2
17:   z 2.0  516   male 2018      3
18:   z 1.0  516   male 2018      3

Обратите внимание, что строки 5 и 17 были обновлены, в то время как строки второй группы, которые дали неправильную статистику, не были затронуты.

x1 приводится к типу numeric перед объединением, чтобы соответствовать типу результата, возвращаемого mean().

Пример данных

Вот примерные данные, состоящие из трех групп. В группе seocnd все значения x1 первого мужского раздела равны NA.

data <- data.table::fread("
add x1 add1  group add2
x    1  514   male 2018
x    2  514   male 2018
x   NA  514 female 2018
x   NA  514 female 2018
x    7  514   male 2018
x    1  514   male 2018
y   NA  515   male 2018
y   NA  515   male 2018
y   NA  515 female 2018
y   NA  515 female 2018
y    7  515   male 2018
y    1  515   male 2018
z    2  516   male 2018
z   NA  516   male 2018
z   NA  516 female 2018
z   NA  516 female 2018
z    7  516   male 2018
z    1  516   male 2018
")

Убедитесь, что сообщение об ошибке вызвано первой мужской группой, полностью состоящей из NA

Когда вышеприведенный примерный набор данных вставлен в код OP, мы можем воспроизвести сообщение об ошибке:

library(dplyr)
data %>% 
  group_by(add,add1,add2) %>%                                          
  mutate(group2 = rleid(group)) %>% 
  group_by(add,add1,add2, group, group2) %>%
  mutate(MEAN = mean(x1[group=="male" & group2==1], na.rm = T),      ## extra code here ##    
         Q25 = quantile(x1[group=="male" & group2==1], 0.25, na.rm = T)) %>%  ## extra code here ##
  group_by(add,add1,add2) %>%                                           
  mutate(x1 = ifelse(group=="male" & group2==3 & x1 > unique(Q25[!is.na(Q25)]), unique(MEAN[!is.na(MEAN)]), x1))%>%
  ungroup() %>%
  select(-group2) %>%
  data.frame()

Ошибка в mutate_impl (.data, точки):
Столбец x1 должен иметь длину 6 (размер группы) или единицу, а не 0

...