将随机缺失值的确切比例添加到 data.frame
add exact proportion of random missing values to data.frame
我想在 R 中将随机 NA
添加到 data.frame。到目前为止,我已经研究了这些问题:
R: Randomly insert NAs into dataframe proportionaly
How do I add random NA
s into a data frame
add random missing values to a complete data frame (in R)
这里提供了很多解决方案,但我找不到符合这5个条件的解决方案:
- 添加真正随机的 NA,而不是按行或按列添加相同的数量
- 处理 data.frame 中可能遇到的每个 class 变量(数字、字符、因子、逻辑、ts..),因此输出必须与输入 data.frame 或矩阵。
- 保证输出中 NA 的确切数量或比例 [注意](许多解决方案导致 NA 的数量较少,因为在同一位置生成了多个)
- 大数据集的计算效率高吗?
- 独立于输入中已经存在的 NA 添加 proportion/number NA。
有人有想法吗?
我已经尝试编写一个函数来执行此操作(在第一个 link 的回答中),但它不符合第 N°3 和 4 点。
谢谢。
[注意] 确切的比例,当然四舍五入为 +/- 1NA。
这是我在 library(imputeMulti)
上的论文中使用的方法,该论文目前正在 JSS 审稿。这会将 NA
插入到整个数据集的随机百分比中并且可以很好地缩放,它不会 保证 一个确切的数字,因为 n * p * pctNA %% 1 != 0
的情况。
createNAs <- function (x, pctNA = 0.1) {
n <- nrow(x)
p <- ncol(x)
NAloc <- rep(FALSE, n * p)
NAloc[sample.int(n * p, floor(n * p * pctNA))] <- TRUE
x[matrix(NAloc, nrow = n, ncol = p)] <- NA
return(x)
}
显然你应该使用随机种子来实现可重复性,这可以在函数调用之前指定。
这是创建用于比较插补方法的基线数据集的一般策略。我相信这就是你想要的,尽管你的问题(如评论中所述)没有明确说明。
编辑:我认为 x
已经完成。所以,我不确定它将如何处理现有的缺失数据。如果你愿意,你当然可以修改代码,尽管这可能会增加运行时间至少 O(n*p)
一些用户报告说 Alex 的回答没有解决我问题的第 5 条条件。事实上,当在已经包含缺失值的数据帧上添加随机 NA
时,新的有时会落在初始值上,最终比例将介于初始比例和所需比例之间......所以我展开Alex 的函数满足所有 5 个条件:
我修改了他的 createNAs
函数,使其启用 3 个选项之一:
- option complement:用 NA 补充到所需的 %
- 选项添加:除了已经存在的那些之外,添加 NA 的百分比
- 选项 none : 添加 NA 的百分比,不管那些已经存在的
对于选项 1 和 2,该函数将递归地工作,直到达到所需的比例 NA
:
createNAs <- function (x, pctNA = 0.0, option = "add"){
prop.NA = function(x) sum(is.na(x))/prod(dim(x))
initial.pctNA = prop.NA(x)
if ( (option =="complement") & (initial.pctNA > pctNA) ){
message("The data already had more NA than the target percentage. Returning original data")
return(x)
}
if ( (option == "none") || (initial.pctNA == 0) ){
n <- nrow(x)
p <- ncol(x)
NAloc <- rep(FALSE, n * p)
NAloc[sample.int(n * p, floor(n * p * pctNA))] <- TRUE
x[matrix(NAloc, nrow = n, ncol = p)] <- NA
return(x)
} else { # if another option than none:
target = ifelse(option=="complement", pctNA, pctNA + initial.pctNA)
while (prop.NA(x) < target) {
prop.remaining.to.add = target - prop.NA(x)
x = createNAs(x, prop.remaining.to.add, option = "none")
}
return(x)
}
}
我想在 R 中将随机 NA
添加到 data.frame。到目前为止,我已经研究了这些问题:
R: Randomly insert NAs into dataframe proportionaly
How do I add random NA
s into a data frame
add random missing values to a complete data frame (in R)
这里提供了很多解决方案,但我找不到符合这5个条件的解决方案:
- 添加真正随机的 NA,而不是按行或按列添加相同的数量
- 处理 data.frame 中可能遇到的每个 class 变量(数字、字符、因子、逻辑、ts..),因此输出必须与输入 data.frame 或矩阵。
- 保证输出中 NA 的确切数量或比例 [注意](许多解决方案导致 NA 的数量较少,因为在同一位置生成了多个)
- 大数据集的计算效率高吗?
- 独立于输入中已经存在的 NA 添加 proportion/number NA。
有人有想法吗? 我已经尝试编写一个函数来执行此操作(在第一个 link 的回答中),但它不符合第 N°3 和 4 点。 谢谢。
[注意] 确切的比例,当然四舍五入为 +/- 1NA。
这是我在 library(imputeMulti)
上的论文中使用的方法,该论文目前正在 JSS 审稿。这会将 NA
插入到整个数据集的随机百分比中并且可以很好地缩放,它不会 保证 一个确切的数字,因为 n * p * pctNA %% 1 != 0
的情况。
createNAs <- function (x, pctNA = 0.1) {
n <- nrow(x)
p <- ncol(x)
NAloc <- rep(FALSE, n * p)
NAloc[sample.int(n * p, floor(n * p * pctNA))] <- TRUE
x[matrix(NAloc, nrow = n, ncol = p)] <- NA
return(x)
}
显然你应该使用随机种子来实现可重复性,这可以在函数调用之前指定。
这是创建用于比较插补方法的基线数据集的一般策略。我相信这就是你想要的,尽管你的问题(如评论中所述)没有明确说明。
编辑:我认为 x
已经完成。所以,我不确定它将如何处理现有的缺失数据。如果你愿意,你当然可以修改代码,尽管这可能会增加运行时间至少 O(n*p)
一些用户报告说 Alex 的回答没有解决我问题的第 5 条条件。事实上,当在已经包含缺失值的数据帧上添加随机 NA
时,新的有时会落在初始值上,最终比例将介于初始比例和所需比例之间......所以我展开Alex 的函数满足所有 5 个条件:
我修改了他的 createNAs
函数,使其启用 3 个选项之一:
- option complement:用 NA 补充到所需的 %
- 选项添加:除了已经存在的那些之外,添加 NA 的百分比
- 选项 none : 添加 NA 的百分比,不管那些已经存在的
对于选项 1 和 2,该函数将递归地工作,直到达到所需的比例 NA
:
createNAs <- function (x, pctNA = 0.0, option = "add"){
prop.NA = function(x) sum(is.na(x))/prod(dim(x))
initial.pctNA = prop.NA(x)
if ( (option =="complement") & (initial.pctNA > pctNA) ){
message("The data already had more NA than the target percentage. Returning original data")
return(x)
}
if ( (option == "none") || (initial.pctNA == 0) ){
n <- nrow(x)
p <- ncol(x)
NAloc <- rep(FALSE, n * p)
NAloc[sample.int(n * p, floor(n * p * pctNA))] <- TRUE
x[matrix(NAloc, nrow = n, ncol = p)] <- NA
return(x)
} else { # if another option than none:
target = ifelse(option=="complement", pctNA, pctNA + initial.pctNA)
while (prop.NA(x) < target) {
prop.remaining.to.add = target - prop.NA(x)
x = createNAs(x, prop.remaining.to.add, option = "none")
}
return(x)
}
}