我想从数据帧的每一行中随机选择两个不重复的值,并将这些值插入同一行数据帧末尾的两列中。我使用的是sample
,但问题是缺少一些数据。我想找到一种方法来使用sample
,忽略丢失的数据。我试图指定na.rm命令,但它不起作用。我能做什么?
让向量像一样是x
x <- c(NA, 3, 4, 5, NA)
现在,子集x仅具有其非NA值,并在该子集上采样。
sample(x[!is.na(x)], 1)
假设我们有以下数据帧:
set.seed(3)
data <- as.data.frame(matrix(sample(c(1:30,rep(NA,20)),replace = TRUE,size = 24),ncol = 3))
data
V1 V2 V3
1 5 20 29
2 12 10 NA
3 NA NA NA
4 NA NA 5
5 NA NA NA
6 NA 8 NA
7 NA NA 9
8 8 2 9
我们可以看到,有时有足够的值可以采样,但有时没有。为了绕过这些边缘情况,我们可以编写一个自定义函数:
sample.function <- function(x){
if(sum(!is.na(x)) == 0) {c(NA,NA)}
else if(sum(!is.na(x)) == 1) {c(x[!is.na(x)],NA)}
else {sample(x[!is.na(x)],size = 2)}}
如果没有非NA值,函数将返回c(NA,NA)
。如果只有一个非NA值,则返回该值和NA。如果有两个或两个以上,则使用x
上的采样函数,该函数是不包括任何NA值的子集。
然后我们可以使用apply
函数将我们的自定义sample.function
应用于我们的数据。Apply按列绑定结果,因此我们可以将其与t()
进行转置。
t(apply(data,1,sample.function))
[,1] [,2]
[1,] 20 29
[2,] 10 12
[3,] NA NA
[4,] 5 NA
[5,] NA NA
[6,] 8 NA
[7,] 9 NA
[8,] 2 9
现在将其添加到原始数据中:
setNames(cbind(data,t(apply(data,1,sample.function))),c("V1","V2","V3","Sample1","Sample2"))
V1 V2 V3 Sample1 Sample2
1 5 20 29 5 29
2 12 10 NA 12 10
3 NA NA NA NA NA
4 NA NA 5 5 NA
5 NA NA NA NA NA
6 NA 8 NA 8 NA
7 NA NA 9 9 NA
8 8 2 9 9 8