为什么 R 'sample' 某些列比其他列多?
Why does R 'sample' some columns more than others?
我正在测试缺失数据对回归分析的影响。因此,使用模拟数据集,我想从一组指定的列中随机删除一部分观察值(不是整行)。我正在使用 'sample' 来执行此操作。不幸的是,这使得某些列的缺失值比其他列多得多。请参阅下面的示例:
#Data frame with 5 columns, 10 rows
DF = data.frame(A = paste(letters[1:10]),B = rnorm(10, 1, 10), C = rnorm(10, 1, 10), D = rnorm(10, 1, 10), E = rnorm(10,1,10))
#Function to randomly delete a proportion (ProportionRemove) of records per column, for a designated set of columns (ColumnStart - ColumnEnd)
RandomSample = function(DataFrame,ColumnStart, ColumnEnd,ProportionRemove){
#ci is the opposite of the proportion
ci = 1-ProportionRemove
Missing = sapply(DataFrame[(ColumnStart:ColumnEnd)], function(x) x[sample(c(TRUE, NA), prob = c(ci,ProportionRemove), size = length(DataFrame), replace = TRUE)])}
#Randomly sample column 2 - 5 within DF, deleting 80% of the observation per column
Test = RandomSample(DF, 2, 5, 0.8)
我知道这有一个随机因素,但在 10 次试验中(10*4 = 40 列),其中 17 列没有数据,而在一次试验中,一列仍然有 6 条记录(而不是比预期的 ~2) - 见下文。
B C D E
[1,] NA 24.004402 7.201558 NA
[2,] NA NA NA NA
[3,] NA 4.029659 NA NA
[4,] NA NA NA NA
[5,] NA 29.377632 NA NA
[6,] NA 3.340918 -2.131747 NA
[7,] NA NA NA NA
[8,] NA 15.967318 NA NA
[9,] NA NA NA NA
[10,] NA -8.078221 NA NA
总而言之,我想在每列中用 NA 替换一定比例的观察值。
非常感谢任何帮助!!!
这对我来说很有意义。正如@Frank 所建议的(在 since-deleted 评论中......*叹息*),"randomness" 可以给你真正的 non-random-looking 结果(Dilbert: Tour of Accounting, 2001-10-25)。
如果您想要保证比率的随机样本,试试这个:
guaranteedSampling <- function(DataFrame, ProportionRemove) {
n <- max(1L, floor(nrow(DataFrame) * ProportionRemove))
inds <- replicate(ncol(DataFrame), sample(nrow(DataFrame), size=n), simplify=FALSE)
DataFrame[] <- mapply(`[<-`, DataFrame, inds, MoreArgs=list(NA), SIMPLIFY=FALSE)
DataFrame
}
set.seed(2)
guaranteedSampling(DF[2:5], 0.8)
# B C D E
# 1 NA NA NA NA
# 2 NA NA NA NA
# 3 NA NA NA NA
# 4 6.792463 10.582938 NA NA
# 5 NA NA -0.612816 NA
# 6 NA -2.278758 NA NA
# 7 NA NA NA 2.245884
# 8 NA NA NA 5.993387
# 9 7.863310 NA 9.042127 NA
# 10 NA NA NA NA
根据@joran 的评论,您想要 nrow(DataFrame)
或 length(x)
您的示例中的具体影响是您正在生成一个包含 5 个元素的向量(因为 DF
有 5 个变量)每个元素成为 NA
的概率为 0.8,成为 [=19 的概率为 0.2 =].
然后这个语句(这是 sapply
对您指定的每一列所做的,在这种情况下我只应用于 DF$B):
DF$B[sample(c(TRUE, NA), prob=c(0.2, 0.8), size = 5, replace=TRUE)]
做一些外行人不是很明显的事情*。这个:
sample(c(TRUE, NA), prob=c(0.2, 0.8), size = 5, replace=TRUE)
给出一个逻辑向量,当它用于提取向量的元素时静默回收。所以假设你最终得到:
NA TRUE NA TRUE NA
当你子集 DF$B
你最终得到这个:
DF$B[c(NA, TRUE, NA, TRUE, NA, NA, TRUE, NA, TRUE, NA)]
请注意在您的示例中,前 5 个数字始终遵循与后 5 个数字相同的模式。这解释了为什么这么多列最终都是 NA
,因为有 0.32768 的概率从 5 NA
中得到 5 个,它被回收到整个列。
您的代码的另一个问题是该函数实际上没有做任何有用的事情,因为您没有指定任何 return 值。此处已更正和清理并使用 http://adv-r.had.co.nz/Style.html:
random_sample <- function(x, col_start, col_end, p) {
sapply(x[col_start:col_end],
function(y) y[sample(c(TRUE, NA), prob = c(1-p, p), size = length(y), replace = TRUE)])
}
*这里的外行包括我!在看到这个问题之前,我不知道逻辑向量在用于提取时会被回收。
我正在测试缺失数据对回归分析的影响。因此,使用模拟数据集,我想从一组指定的列中随机删除一部分观察值(不是整行)。我正在使用 'sample' 来执行此操作。不幸的是,这使得某些列的缺失值比其他列多得多。请参阅下面的示例:
#Data frame with 5 columns, 10 rows
DF = data.frame(A = paste(letters[1:10]),B = rnorm(10, 1, 10), C = rnorm(10, 1, 10), D = rnorm(10, 1, 10), E = rnorm(10,1,10))
#Function to randomly delete a proportion (ProportionRemove) of records per column, for a designated set of columns (ColumnStart - ColumnEnd)
RandomSample = function(DataFrame,ColumnStart, ColumnEnd,ProportionRemove){
#ci is the opposite of the proportion
ci = 1-ProportionRemove
Missing = sapply(DataFrame[(ColumnStart:ColumnEnd)], function(x) x[sample(c(TRUE, NA), prob = c(ci,ProportionRemove), size = length(DataFrame), replace = TRUE)])}
#Randomly sample column 2 - 5 within DF, deleting 80% of the observation per column
Test = RandomSample(DF, 2, 5, 0.8)
我知道这有一个随机因素,但在 10 次试验中(10*4 = 40 列),其中 17 列没有数据,而在一次试验中,一列仍然有 6 条记录(而不是比预期的 ~2) - 见下文。
B C D E
[1,] NA 24.004402 7.201558 NA
[2,] NA NA NA NA
[3,] NA 4.029659 NA NA
[4,] NA NA NA NA
[5,] NA 29.377632 NA NA
[6,] NA 3.340918 -2.131747 NA
[7,] NA NA NA NA
[8,] NA 15.967318 NA NA
[9,] NA NA NA NA
[10,] NA -8.078221 NA NA
总而言之,我想在每列中用 NA 替换一定比例的观察值。
非常感谢任何帮助!!!
这对我来说很有意义。正如@Frank 所建议的(在 since-deleted 评论中......*叹息*),"randomness" 可以给你真正的 non-random-looking 结果(Dilbert: Tour of Accounting, 2001-10-25)。
如果您想要保证比率的随机样本,试试这个:
guaranteedSampling <- function(DataFrame, ProportionRemove) {
n <- max(1L, floor(nrow(DataFrame) * ProportionRemove))
inds <- replicate(ncol(DataFrame), sample(nrow(DataFrame), size=n), simplify=FALSE)
DataFrame[] <- mapply(`[<-`, DataFrame, inds, MoreArgs=list(NA), SIMPLIFY=FALSE)
DataFrame
}
set.seed(2)
guaranteedSampling(DF[2:5], 0.8)
# B C D E
# 1 NA NA NA NA
# 2 NA NA NA NA
# 3 NA NA NA NA
# 4 6.792463 10.582938 NA NA
# 5 NA NA -0.612816 NA
# 6 NA -2.278758 NA NA
# 7 NA NA NA 2.245884
# 8 NA NA NA 5.993387
# 9 7.863310 NA 9.042127 NA
# 10 NA NA NA NA
根据@joran 的评论,您想要 nrow(DataFrame)
或 length(x)
您的示例中的具体影响是您正在生成一个包含 5 个元素的向量(因为 DF
有 5 个变量)每个元素成为 NA
的概率为 0.8,成为 [=19 的概率为 0.2 =].
然后这个语句(这是 sapply
对您指定的每一列所做的,在这种情况下我只应用于 DF$B):
DF$B[sample(c(TRUE, NA), prob=c(0.2, 0.8), size = 5, replace=TRUE)]
做一些外行人不是很明显的事情*。这个:
sample(c(TRUE, NA), prob=c(0.2, 0.8), size = 5, replace=TRUE)
给出一个逻辑向量,当它用于提取向量的元素时静默回收。所以假设你最终得到:
NA TRUE NA TRUE NA
当你子集 DF$B
你最终得到这个:
DF$B[c(NA, TRUE, NA, TRUE, NA, NA, TRUE, NA, TRUE, NA)]
请注意在您的示例中,前 5 个数字始终遵循与后 5 个数字相同的模式。这解释了为什么这么多列最终都是 NA
,因为有 0.32768 的概率从 5 NA
中得到 5 个,它被回收到整个列。
您的代码的另一个问题是该函数实际上没有做任何有用的事情,因为您没有指定任何 return 值。此处已更正和清理并使用 http://adv-r.had.co.nz/Style.html:
random_sample <- function(x, col_start, col_end, p) {
sapply(x[col_start:col_end],
function(y) y[sample(c(TRUE, NA), prob = c(1-p, p), size = length(y), replace = TRUE)])
}
*这里的外行包括我!在看到这个问题之前,我不知道逻辑向量在用于提取时会被回收。