将replace_na用于多个数据子集

时间:2018-02-06 08:59:27

标签: r replace subset

我正在尝试使用每个student_id的子集行数据中随机生成的值替换多个列变量中的NA: data snapshot

因此对于学生3,收缩期需要更换两个NAs。我使用student 3子集中每个变量的最小值和最大值来生成随机值。

library(dplyr)
library(tidyr)
library(tibble)
library(tidyverse)
dplyr::filter(exercise, student_id == "3") %>% replace_na(list(systolic= round(sample(runif(1000, 125,130),2),0), 
diastolic =round(sample(runif(1000, 85,85),3),0), heart_rate= round(sample(runif(1000, 79,86),2),0), 
phys_score = round(sample(runif(1000, 8,9),2),0)

然而,仅当一个NA 需要替换时才有效:successfully replaced systolic NA values。当我尝试替换多个NA时,会出现此错误。

Error: Replacement for `systolic` is length 2, not length 1

有没有办法解决这个问题?我尝试将列变量转换为数据帧而不是现在的向量,但它只返回原始数据而没有任何替换更改。

有没有更简单的方法呢?任何建议/意见将不胜感激。感谢。

1 个答案:

答案 0 :(得分:0)

一种使事情变得更加自动化但可能不必要地复杂的解决方案。

从mtcars数据集生成一些分组的缺失数据

library(magrittr)
library(purrr)
library(dplyr)
library(stringr)
library(tidyr)

## Generate some missing data with a subset of car make
mtcars_miss <- mtcars %>%
  as_tibble(rownames = "car") %>%
  select(car) %>% 
  separate(car, c("make", "name"), " ") %>% 
  bind_cols(mtcars[, -1] %>%   
              map_df(~.[sample(c(TRUE, NA), prob = c(0.8, 0.2), 
                               size = length(.), replace = TRUE)])) %>% 
  filter(make %in% c("Mazda", "Hornet", "Merc"))

通过在最小值和最大值内采样并取决于某个组(此处为make)来替换给定变量中的na值的函数。

replace_na_sample <- function(df_miss, var, group = "make") {

  var <- enquo(var)

  df_miss %>% 
    group_by(.dots = group) %>% 
    mutate(replace_var := round(runif(n(), min(!!var, na.rm = T),
                                      max(!!var, na.rm = T)), 0)) %>% 
    rowwise %>% 
    mutate_at(.vars = vars(!!var),
              .funs = funs(replace_na(., replace_var))) %>% 
    select(-replace_var) %>% 
    ungroup

}

示例替换多列中的多个缺失值。

mtcars_replaced <- mtcars_miss  %>% 
  replace_na_sample(cyl, group = "make") %>% 
  replace_na_sample(disp, group = "make") %>%
  replace_na_sample(hp, group = "make")