Есть ли в R функция, позволяющая заменить NA средним критерием строки? - PullRequest
2 голосов
/ 04 марта 2020

У меня есть столбик, с которым я работаю с NA в столбце. Я хочу заменить NA (цифра c столбец) средним значением столбца и столбца queue_name. Например, NA для второй строки будет заменен средним значением, где очередь - «B». NA должно быть 150 для всех очередей B с NA.

call_center_tbl <- tribble(~queue_name, ~talk_time,
        "A", 230,
        "B", "NA",
        "C", 150,
        "A", 200,
        "B", 100,
        "B", 200,
        "C", "NA")

Надеюсь, это имеет смысл. Спасибо!

Ответы [ 2 ]

3 голосов
/ 04 марта 2020

Один из способов использования data.table заключается в следующем. В ваших данных, talk_time символ. Поэтому я преобразовал столбец в цифру c. Затем для каждого queue_name я использовал replace(), чтобы заменить NA средним значением каждой группы.

library(data.table)

setDT(call_center_tbl)[, talk_time := as.numeric(talk_time)][,
   talk_time :=  replace(talk_time,
                         list = which(is.na(talk_time)),
                         values = mean(talk_time, na.rm = TRUE)),
   by = queue_name][]

   queue_name talk_time
1:          A       230
2:          B       150
3:          C       150
4:          A       200
5:          B       100
6:          B       200
7:          C       150

Вы можете использовать nafill() вместо replace(), если хотите .

setDT(call_center_tbl)[, talk_time := as.numeric(talk_time)][,
                          talk_time := nafill(x = talk_time, fill = mean(talk_time, na.rm = TRUE)),
                                  by = queue_name][]
2 голосов
/ 04 марта 2020

Вы можете использовать оператор ifelse после группировки значений на основе "queue_name":

library(dplyr)
call_center_tbl %>% 
  mutate(talk_time = as.numeric(talk_time)) %>% 
  group_by(queue_name) %>% 
  mutate(talk_time = ifelse(is.na(talk_time), mean(talk_time, na.rm =TRUE), talk_time))

# A tibble: 7 x 2
# Groups:   queue_name [3]
  queue_name talk_time
  <chr>          <dbl>
1 A                230
2 B                150
3 C                150
4 A                200
5 B                100
6 B                200
7 C                150

Вы также можете использовать функцию replace_na из пакета tidyr вместо оператора ifelse :

library(tidyr)
library(dplyr)
call_center_tbl %>% 
  mutate(talk_time = as.numeric(talk_time)) %>% 
  group_by(queue_name) %>% 
  mutate(talk_time = replace_na(talk_time, mean(talk_time, na.rm = TRUE)))
...