假设我们有以下data.frame:
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