R:用 NA 随机替换值
R: Randomly Replace Values with NA
我正在使用 R 编程语言。我正在尝试 select 数据集中 10% 的元素(不包括第一列中的元素)并将它们替换为 NA。我尝试使用以下代码执行此操作:
library(longitudinalData)
data(artificialLongData)
second_dataset = artificialLongData
second_dataset[sample(nrow(second_dataset),0.1*nrow(second_dataset ))]<- NA
这会产生以下错误:
Error in `[<-.data.frame`(`*tmp*`, sample(nrow(second_dataset), 0.1 * :
new columns would leave holes after existing columns
有人可以告诉我如何解决这个问题吗?
谢谢!
注意:最终结果应如下所示:
id t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10
1 s1 NA NA -1.85 -2.05 1.01 1.56 NA 0.52 -0.06 -1.09 0.44
2 s2 -4.88 -2.95 -2.38 3.73 -2.77 1.72 -0.99 -0.70 NA 2.38 -0.72
3 s3 NA -0.86 NA -2.04 -1.18 4.89 NA 0.50 4.90 -0.52 NA
您可以 replace
lapply
中的随机元素。
set.seed(42)
r1 <- as.data.frame(lapply(dat, \(x) replace(x, sample(length(x), .1*length(x)), NA)))
r1
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1 NA 7 NA 10 3 11 4 4 NA 7
# 2 6 6 8 8 4 11 NA 8 10 9
# 3 1 12 4 5 12 3 10 3 11 1
# 4 3 10 6 2 11 NA 3 11 2 11
# 5 8 NA 10 12 5 7 2 9 4 10
# 6 12 4 9 12 9 2 7 9 8 8
# 7 7 5 9 4 2 12 12 3 4 4
# 8 12 5 3 1 6 1 4 7 6 NA
# 9 4 6 12 NA 5 8 4 4 6 7
# 10 3 2 11 3 NA 5 4 NA 2 4
mean(is.na(r1))
# [1] 0.1
但是,这会将每列中的 .1 个值替换为 NA
。如果我们希望每个单元格都以 .1 的概率被 NA
替换,我们可以在两个 MARGINS=1:2
.
上使用 apply
set.seed(42)
p <- .1
r2 <- as.data.frame(apply(dat, 1:2, \(x) sample(c(x, NA), 1, prob=c((1 - p), p))))
r2
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1 NA 7 NA 10 3 11 4 4 12 7
# 2 NA 6 8 8 4 11 NA 8 10 9
# 3 1 NA NA 5 12 3 10 3 11 1
# 4 3 10 NA 2 NA 9 3 11 2 NA
# 5 8 12 10 12 5 7 2 9 4 NA
# 6 12 NA 9 12 NA 2 7 9 8 8
# 7 7 NA 9 4 2 12 12 3 4 4
# 8 12 5 NA 1 6 1 4 7 6 12
# 9 4 6 12 NA NA 8 4 4 6 7
# 10 3 2 11 3 3 5 4 8 2 4
mean(is.na(r2))
# [1] 0.16
如果可以强制转换数据as.matrix
,您可以将其视为向量
set.seed(42)
m <- as.matrix(dat)
m[sample(seq_along(m), .1*length(m))] <- NA
m
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# [1,] 6 7 1 10 3 11 4 NA 12 7
# [2,] 6 6 8 8 4 11 10 8 10 9
# [3,] 1 12 4 5 12 3 10 3 11 1
# [4,] 3 10 NA 2 11 9 3 NA 2 11
# [5,] 8 12 NA 12 5 7 NA 9 4 10
# [6,] 12 4 9 12 9 2 7 9 8 8
# [7,] 7 5 9 4 NA 12 12 3 4 4
# [8,] 12 NA 3 1 6 1 4 7 6 12
# [9,] 4 6 12 3 NA 8 4 4 NA 7
# [10,] 3 2 11 3 3 5 4 8 2 NA
mean(is.na(m))
# [1] 0.1
并强制返回 "data.frame"
。
dat_na <- as.data.frame(m) |> type.convert(as.is=TRUE)
type.convert
像 "numeric"
和 "character"
一样负责返回 类,因为矩阵只能有一种模式。请注意,您可能会在此过程中丢失属性。
数据:
dat <- structure(list(X1 = c(6L, 6L, 1L, 3L, 8L, 12L, 7L, 12L, 4L, 3L
), X2 = c(7L, 6L, 12L, 10L, 12L, 4L, 5L, 5L, 6L, 2L), X3 = c(1L,
8L, 4L, 6L, 10L, 9L, 9L, 3L, 12L, 11L), X4 = c(10L, 8L, 5L, 2L,
12L, 12L, 4L, 1L, 3L, 3L), X5 = c(3L, 4L, 12L, 11L, 5L, 9L, 2L,
6L, 5L, 3L), X6 = c(11L, 11L, 3L, 9L, 7L, 2L, 12L, 1L, 8L, 5L
), X7 = c(4L, 10L, 10L, 3L, 2L, 7L, 12L, 4L, 4L, 4L), X8 = c(4L,
8L, 3L, 11L, 9L, 9L, 3L, 7L, 4L, 8L), X9 = c(12L, 10L, 11L, 2L,
4L, 8L, 4L, 6L, 6L, 2L), X10 = c(7L, 9L, 1L, 11L, 10L, 8L, 4L,
12L, 7L, 4L)), class = "data.frame", row.names = c(NA, -10L))
我正在使用 R 编程语言。我正在尝试 select 数据集中 10% 的元素(不包括第一列中的元素)并将它们替换为 NA。我尝试使用以下代码执行此操作:
library(longitudinalData)
data(artificialLongData)
second_dataset = artificialLongData
second_dataset[sample(nrow(second_dataset),0.1*nrow(second_dataset ))]<- NA
这会产生以下错误:
Error in `[<-.data.frame`(`*tmp*`, sample(nrow(second_dataset), 0.1 * :
new columns would leave holes after existing columns
有人可以告诉我如何解决这个问题吗?
谢谢!
注意:最终结果应如下所示:
id t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10
1 s1 NA NA -1.85 -2.05 1.01 1.56 NA 0.52 -0.06 -1.09 0.44
2 s2 -4.88 -2.95 -2.38 3.73 -2.77 1.72 -0.99 -0.70 NA 2.38 -0.72
3 s3 NA -0.86 NA -2.04 -1.18 4.89 NA 0.50 4.90 -0.52 NA
您可以 replace
lapply
中的随机元素。
set.seed(42)
r1 <- as.data.frame(lapply(dat, \(x) replace(x, sample(length(x), .1*length(x)), NA)))
r1
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1 NA 7 NA 10 3 11 4 4 NA 7
# 2 6 6 8 8 4 11 NA 8 10 9
# 3 1 12 4 5 12 3 10 3 11 1
# 4 3 10 6 2 11 NA 3 11 2 11
# 5 8 NA 10 12 5 7 2 9 4 10
# 6 12 4 9 12 9 2 7 9 8 8
# 7 7 5 9 4 2 12 12 3 4 4
# 8 12 5 3 1 6 1 4 7 6 NA
# 9 4 6 12 NA 5 8 4 4 6 7
# 10 3 2 11 3 NA 5 4 NA 2 4
mean(is.na(r1))
# [1] 0.1
但是,这会将每列中的 .1 个值替换为 NA
。如果我们希望每个单元格都以 .1 的概率被 NA
替换,我们可以在两个 MARGINS=1:2
.
apply
set.seed(42)
p <- .1
r2 <- as.data.frame(apply(dat, 1:2, \(x) sample(c(x, NA), 1, prob=c((1 - p), p))))
r2
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# 1 NA 7 NA 10 3 11 4 4 12 7
# 2 NA 6 8 8 4 11 NA 8 10 9
# 3 1 NA NA 5 12 3 10 3 11 1
# 4 3 10 NA 2 NA 9 3 11 2 NA
# 5 8 12 10 12 5 7 2 9 4 NA
# 6 12 NA 9 12 NA 2 7 9 8 8
# 7 7 NA 9 4 2 12 12 3 4 4
# 8 12 5 NA 1 6 1 4 7 6 12
# 9 4 6 12 NA NA 8 4 4 6 7
# 10 3 2 11 3 3 5 4 8 2 4
mean(is.na(r2))
# [1] 0.16
如果可以强制转换数据as.matrix
,您可以将其视为向量
set.seed(42)
m <- as.matrix(dat)
m[sample(seq_along(m), .1*length(m))] <- NA
m
# X1 X2 X3 X4 X5 X6 X7 X8 X9 X10
# [1,] 6 7 1 10 3 11 4 NA 12 7
# [2,] 6 6 8 8 4 11 10 8 10 9
# [3,] 1 12 4 5 12 3 10 3 11 1
# [4,] 3 10 NA 2 11 9 3 NA 2 11
# [5,] 8 12 NA 12 5 7 NA 9 4 10
# [6,] 12 4 9 12 9 2 7 9 8 8
# [7,] 7 5 9 4 NA 12 12 3 4 4
# [8,] 12 NA 3 1 6 1 4 7 6 12
# [9,] 4 6 12 3 NA 8 4 4 NA 7
# [10,] 3 2 11 3 3 5 4 8 2 NA
mean(is.na(m))
# [1] 0.1
并强制返回 "data.frame"
。
dat_na <- as.data.frame(m) |> type.convert(as.is=TRUE)
type.convert
像 "numeric"
和 "character"
一样负责返回 类,因为矩阵只能有一种模式。请注意,您可能会在此过程中丢失属性。
数据:
dat <- structure(list(X1 = c(6L, 6L, 1L, 3L, 8L, 12L, 7L, 12L, 4L, 3L
), X2 = c(7L, 6L, 12L, 10L, 12L, 4L, 5L, 5L, 6L, 2L), X3 = c(1L,
8L, 4L, 6L, 10L, 9L, 9L, 3L, 12L, 11L), X4 = c(10L, 8L, 5L, 2L,
12L, 12L, 4L, 1L, 3L, 3L), X5 = c(3L, 4L, 12L, 11L, 5L, 9L, 2L,
6L, 5L, 3L), X6 = c(11L, 11L, 3L, 9L, 7L, 2L, 12L, 1L, 8L, 5L
), X7 = c(4L, 10L, 10L, 3L, 2L, 7L, 12L, 4L, 4L, 4L), X8 = c(4L,
8L, 3L, 11L, 9L, 9L, 3L, 7L, 4L, 8L), X9 = c(12L, 10L, 11L, 2L,
4L, 8L, 4L, 6L, 6L, 2L), X10 = c(7L, 9L, 1L, 11L, 10L, 8L, 4L,
12L, 7L, 4L)), class = "data.frame", row.names = c(NA, -10L))