转换数据框中行中的部分值

Convert part of the values in rows in a data frame

我有一个如下所示的数据框:

df

colA colB
0     0
1     1
0     1
0     1
0     1
1     0
0     0
1     1
0     1

我想将colA中0的一定比例转为NA,colB中1的一定比例转为NA

如果我这样做:

df["colA"][df["colA"] == 0] <- NA

A列中的所有0都将转换为NA,但我只想转换其中一半

同样,对于colB我只想转换1的1/3:

df["colB"][df["colB"] == 1] <- NA

预期输出:

   colA colB
    0     0
    1     1
    NA    1
    0     1
    NA    1
    1     0
    0     0
    1     NA
    NA    NA

一种方式

tmp=which(df["colA"]==0)
df$colA[sample(tmp,round(length(tmp)/2))]=NA

colB 相似

tmp=which(df["colB"]==1)
df$colB[sample(tmp,round(length(tmp)/3))]=NA

您可以使用 missForest 包中的 prodNA

set.seed(1)
library(missForest)
df[df$colA == 0, "colA"] <- prodNA(df[df$colA == 0, "colA", drop=F], noNA = 0.5)
df[df$colB == 1, "colB"] <- prodNA(df[df$colB == 1, "colB", drop=F], noNA = 1/3)
df

  colA colB
1   NA    0
2    1   NA
3    0   NA
4   NA    1
5   NA    1
6    1    0
7    0    0
8    1    1
9    0    1

我将在这里贡献一个 tidyverse 方法。

library(tidyverse)

df %>% mutate(id_colA = ifelse(colA == 1,  NA, 1:n()),
              colA = ifelse(id_colA %in% sample(na.omit(id_colA), sum(!is.na(id_colA))/2), NA, colA),
              id_colB = ifelse(colB == 0, NA, 1:n()),
              colB = ifelse(id_colB %in% sample(na.omit(id_colB), sum(!is.na(id_colB))/3), NA, colB)) %>%
  select(-starts_with("id_"))