【发布时间】:2014-07-23 20:58:49
【问题描述】:
我有一个数据框,其中包含大约 20 个数字列,每个列都包含大量的 NA 值。我想选择这些列的一个子集,这将为我提供包含零 NA 值的最多行。详尽的搜索会花费大量的计算时间——有没有更好的方法来获得近似值?
这是一个数据框较小的示例(完全任意):
set.seed(2)
foo = as.data.frame(matrix(rnorm(200), nr = 20))
foo[sapply(foo, function(x) x > abs(x[1]))] = NA
foo = foo[-1, ]
round(foo, 3)
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
2 0.185 -1.200 -1.959 NA -1.696 0.261 0.139 0.410 -0.638 -1.262
3 NA 1.590 -0.842 -0.703 -0.533 -0.314 NA -0.807 -0.268 0.392
4 -1.130 1.955 NA 0.158 -1.372 -0.750 -0.431 0.086 0.360 -1.131
5 -0.080 0.005 NA 0.506 -2.208 -0.862 -1.044 NA -1.313 0.544
6 0.132 -2.452 NA -0.820 NA NA 0.538 -0.654 -0.884 NA
7 0.708 0.477 -0.305 -1.999 -0.653 0.940 -0.670 NA NA 0.025
8 -0.240 -0.597 -0.091 -0.479 -0.285 NA 0.639 0.550 -2.099 0.515
9 NA 0.792 -0.184 0.084 -0.387 -0.421 -1.724 -0.807 -1.239 -0.654
10 -0.139 0.290 -1.199 -0.895 0.387 -0.351 -1.742 -0.997 NA 0.504
11 0.418 0.739 -0.838 -0.921 NA -1.027 0.690 NA NA -1.272
12 NA 0.319 NA 0.330 NA -0.251 0.331 -0.169 NA -0.077
13 -0.393 1.076 -0.562 -0.142 -1.184 0.472 0.871 NA 0.057 -1.345
14 -1.040 -0.284 NA 0.435 -1.358 NA -2.016 -0.844 0.324 -0.266
15 NA -0.777 -1.048 -0.054 -1.513 0.564 1.213 NA -0.905 NA
16 -2.311 -0.596 -1.966 -0.907 -1.253 0.456 1.200 -1.343 -0.652 0.701
17 0.879 -1.726 -0.323 1.304 NA NA 1.032 NA -0.262 -0.443
18 0.036 -0.903 NA 0.772 0.008 NA 0.786 0.464 -0.935 -0.789
19 NA -0.559 NA 1.053 -0.843 0.107 NA 0.268 NA -0.857
20 0.432 -0.247 NA -1.410 -0.601 -0.783 -1.454 NA -1.624 -0.746
dim(na.omit(foo))
[1] 1 10
这是我制定详尽搜索的方式:
best.list = list()
for (i in 5:ncol(foo)) {
# get best subset for each size
collist = combn(ncol(foo), i)
numobs = apply(collist, 2, function(x) nrow(na.omit(foo[, x])))
cat("for subset size", i, "most complete obs is", max(numobs), "\n")
best = which(numobs == max(numobs))[1]
best.list = c(best.list, list(collist[, best]))
}
例如,best.list[[1]] 告诉我,如果我保留 5 列,我可以有 12 个完整的观察值(NA 为零的行),我应该选择第 1、2、4、7 和 10 列。
虽然这适用于非常小的数据帧,但对于较大的数据帧,它很快就会变得令人望而却步。 R中有没有办法有效地估计给定大小的最佳子集?我唯一能找到的是subselect 包,尽管我不知道如何为手头的问题实现它的方法。
【问题讨论】:
-
您真的需要最好的解决方案来解决您的问题吗?如果您可以接受近似值,那么贪婪的方法可能会有所帮助(至少很容易)。一次选择一列,在每个步骤中选择一个与您已经选择的列一起产生最完整案例的列。
-
...具体来说,您有一个离散优化问题。定义
X <- (is.na(foo))+0。那么你的问题相当于找到一个 0/1 向量v与sum(v)==k和sum((X%*%v)[,1]==0)最大。可能在 R 中解决这个问题的具体方法是您最不用担心的,R 在优化方面并不是很强大 - 您可能需要先考虑算法。 CRAN 优化任务视图可能会有所帮助,虽然我没有马上找到任何东西:cran.r-project.org/web/views/Optimization.html -
一个近似值很好。我对优化知之甚少,但我得到了贪婪算法的要点。我会试试看的。
标签: r optimization mathematical-optimization subquery