如何使用R中前一行的样本数据填充非相邻行?

时间:2015-05-12 17:36:53

标签: r random sample

我的数据包含唯一标识符,类别和说明。 以下是玩具数据集。

prjnumber <- c(1,2,3,4,5,6,7,8,9,10)
category <- c("based","trill","lit","cold",NA,"epic", NA,NA,NA,NA)
description <- c("skip class",
                 "dunk on brayden",
                 "record deal",
                 "fame and fortune",
                 NA,
                 "female attention",
                 NA,NA,NA,NA)
toy.df <- data.frame(prjnumber, category, description)

> toy.df
       prjnumber category      description
    1          1    based       skip class
    2          2    trill  dunk on brayden
    3          3      lit      record deal
    4          4     cold fame and fortune
    5          5     <NA>             <NA>
    6          6     epic female attention
    7          7     <NA>             <NA>
    8          8     <NA>             <NA>
    9          9     <NA>             <NA>
    10        10     <NA>             <NA>

我想随机抽样&#39;类别&#39;和&#39;描述&#39;已填充的行中的列,用作缺少数据的行的填充。 最终的数据框架将是完整的,并且只依赖于包含数据的最初5行。该解决方案将保持列间相关性。 预期的输出是:

> toy.df
       prjnumber category      description
    1          1    based       skip class
    2          2    trill  dunk on brayden
    3          3      lit      record deal
    4          4     cold fame and fortune
    5          5      lit      record deal
    6          6     epic female attention
    7          7    based       skip class
    8          8    based       skip class
    9          9     lit       record deal
    10        10   trill   dunk on brayden

3 个答案:

答案 0 :(得分:5)

complete = na.omit(toy.df)
toy.df[is.na(toy.df$category), c("category", "description")] =
    complete[sample(1:nrow(complete), size = sum(is.na(toy.df$category)), replace = TRUE),
             c("category", "description")]
toy.df
#    prjnumber category      description
# 1          1    based       skip class
# 2          2    trill  dunk on brayden
# 3          3      lit      record deal
# 4          4     cold fame and fortune
# 5          5      lit      record deal
# 6          6     epic female attention
# 7          7     cold fame and fortune
# 8          8    based       skip class
# 9          9     epic female attention
# 10        10     epic female attention

如果您没有为NA行填写的唯一标识符开始,这似乎会更直接......

答案 1 :(得分:5)

你可以尝试

library(dplyr)
toy.df %>%
      mutate_each(funs(replace(., is.na(.), sample(.[!is.na(.)]))), 2:3) 

根据新信息,我们可能需要在funs中使用数字索引。

toy.df %>% 
   mutate(indx= replace(row_number(), is.na(category), 
           sample(row_number()[!is.na(category)], replace=TRUE)))  %>%
   mutate_each(funs(.[indx]), 2:3) %>% 
   select(-indx)

答案 2 :(得分:2)

使用Base R一次填充一个字段a,使用类似的东西(不保留字段之间的相关性):

fields  <-  c('category','description')
for(field in fields){
    missings  <-  is.na(toy.df[[field]])
    toy.df[[field]][missings]  <-  sample(toy.df[[field]][!missings],sum(missings),T)
}

并同时填充它们(保留字段之间的相关性)使用类似:

missings  <-  apply(toy.df[,fields],
                    1,
                    function(x)any(is.na(x)))

toy.df[missings,fields]  <-  toy.df[!missings,fields][sample(sum(!missings),
                                                           sum(missings),
                                                           T),]

当然,要避免apply(x,1,fun)中的隐式for循环,您可以使用:

rowAny <- function(x) rowSums(x) > 0
missings  <-  rowAny(toy.df[,fields])