按比例随机将NAmes插入数据框

时间:2014-12-13 00:36:32

标签: r dataframe na missing-data

我有一个完整的数据框。我希望数据帧中20%的值被NA替换,以模拟随机丢失的数据。

A <- c(1:10)
B <- c(11:20)
C <- c(21:30)
df<- data.frame(A,B,C)

有人能建议快速做到这一点吗?

6 个答案:

答案 0 :(得分:13)

df <- data.frame(A = 1:10, B = 11:20, c = 21:30)
head(df)
##   A  B  c
## 1 1 11 21
## 2 2 12 22
## 3 3 13 23
## 4 4 14 24
## 5 5 15 25
## 6 6 16 26

as.data.frame(lapply(df, function(cc) cc[ sample(c(TRUE, NA), prob = c(0.85, 0.15), size = length(cc), replace = TRUE) ]))
##     A  B  c
## 1   1 11 21
## 2   2 12 22
## 3   3 13 23
## 4   4 14 24
## 5   5 NA 25
## 6   6 16 26
## 7  NA 17 27
## 8   8 18 28
## 9   9 19 29
## 10 10 20 30

这是一个随机过程,因此每次都不会给出15%。

答案 1 :(得分:5)

您可以取消列出data.frame,然后随机抽样,然后放回data.frame。

df <- unlist(df)
n <- length(df) * 0.15
df[sample(df, n)] <- NA
as.data.frame(matrix(df, ncol=3))

使用sample()可以通过一系列不同的方式完成。

答案 2 :(得分:5)

如果您想使用lapply代替> library(purrr) > df <- data.frame(A = 1:10, B = 11:20, C = 21:30) > df A B C 1 1 11 21 2 2 12 22 3 3 13 23 4 4 14 24 5 5 15 25 6 6 16 26 7 7 17 27 8 8 18 28 9 9 19 29 10 10 20 30 > map_df(df, function(x) {x[sample(c(TRUE, NA), prob = c(0.8, 0.2), size = length(x), replace = TRUE)]}) # A tibble: 10 x 3 A B C <int> <int> <int> 1 1 11 21 2 2 12 22 3 NA 13 NA 4 4 14 NA 5 5 15 25 6 6 16 26 7 7 17 27 8 8 NA 28 9 9 19 29 10 10 20 30 ,您也可以这样做:

curl --request POST \
 --header "iplanetdirectorypro: AQIC5wM2LY4SfczUFNs-TJwFrCVAKgR0NulIAyNaIkQmjis.*AAJTSQACMDEA
 AlNLABQtNTQ3NDE2Njc5ODk4MjYzMzA2MQ..*" \
 --header "Content-Type: application/json"
http://openam.example.com:8080/openam/json/users?_action=idFromSession

答案 3 :(得分:1)

相同的结果,使用二项分布:

dd=dim(df)
nna=20/100 #overall
df1<-df
df1[matrix(rbinom(prod(dd), size=1,prob=nna)==1,nrow=dd[1])]<-NA
df1

答案 4 :(得分:1)

我可以建议第一个设计用于执行此操作的函数(ggNAadd),并使用第二个函数对其进行改进,提供创建的NAs的图形分布(ggNA)

什么是可能输入一定比例的固定数量的NA。

ggNAadd = function(data, amount, plot=F){
  temp <- data
  amount2 <- ifelse(amount<1, round(prod(dim(data))*amount), amount)
  if (amount2 >= prod(dim(data))) stop("exceeded data size")
  for (i in 1:amount2) temp[sample.int(nrow(temp), 1), sample.int(ncol(temp), 1)] <- NA
  if (plot) print(ggNA(temp))
  return(temp)
}

绘图功能:

ggNA = function(data, alpha=0.5){
  require(ggplot2)
  DF <- data
  if (!is.matrix(data)) DF <- as.matrix(DF)
  to.plot <- cbind.data.frame('y'=rep(1:nrow(DF), each=ncol(DF)), 
                              'x'=as.logical(t(is.na(DF)))*rep(1:ncol(DF), nrow(DF)))
  size <- 20 / log( prod(dim(DF)) )  # size of point depend on size of table
  g <- ggplot(data=to.plot) + aes(x,y) +
    geom_point(size=size, color="red", alpha=alpha) +
    scale_y_reverse() + xlim(1,ncol(DF)) +
    ggtitle("location of NAs in the data frame") +
    xlab("columns") + ylab("lines")
  pc <- round(sum(is.na(DF))/prod(dim(DF))*100, 2) # % NA
  print(paste("percentage of NA data: ", pc))
  return(g)
}

给出(使用ggplot2作为图形输出):

ggNAadd(df, amount=0.20, plot=TRUE)
## [1] "percentage of NA data:  20"
##     A  B  c
## 1   1 11 21
## 2   2 12 22
## 3   3 13 23
## 4   4 NA 24
## ..

enter image description here

当然,正如前面提到的,如果你问过多的NAs,实际百分比会因重复而下降。

答案 5 :(得分:0)

一种mutate_all方法:

df %>% 
  dplyr::mutate_all(~ifelse(sample(c(TRUE, FALSE), size = length(.), replace = TRUE, prob = c(0.8, 0.2)),
         as.character(.), NA))