数据框中最佳的非缺失子集

3

我有一个数据框,大小为160560 x 171。有很多数据,但几乎90%的数据是NA。

我想要使用的算法(我们称之为ALG)不能容忍数据框中的任何NA。我的想法是找到这个数据框的最佳子集,并在其上使用ALG。

当我说子集时,我指的是数据框的n列子集(n<171),其中不包含任何NA(所有行都是完整的)。

当我说最佳时,我指的是该子集具有可能拥有的最多行数。例如,如果我有两个包含20列的子集,第一个有1152行,第二个有2254行,则选择第二个。

问题在于简单的组合学无法解决这个问题,因为combn(1:171,20)的结果超过了5*10^25。

在R中是否有任何库可以帮助我处理此问题?


那么,没有绝对的最小列数吗? - talat
1
在这种情况下,您可以简单地选择具有最少NA数量的列(检查colSums(is.na(df)))。 - talat
1
它确实是这样,您的标准是最大行数,而不是最大值数量。 - Axeman
2
你必须对最小列数施加限制,或者将优化标准更改为跨列的非NA值的最大数量(而不是行数!) - talat
1
也许遗传算法可以帮忙解决这个问题?排列优化? - Fernando
显示剩余8条评论
1个回答

1
这是使用crossprod的一种方法。这将为您提供具有给定列数中最大非NA行数的列。无论如何,您都必须选择要获取的列数。否则,您将始终选择具有最少NA的单个列。
首先,让我们为此示例创建一个初始矩阵。此时必须为矩阵。根据需要在数据上使用as.matrix
set.seed(2)
x <- runif(150)
x[sample(1:150, 15, replace = FALSE)] <- NA
x <- matrix(x,ncol=10)
round(x,1)
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]  0.2  0.9  0.0  0.8  0.8  0.8  1.0  0.6  0.0   0.7
 [2,]  0.7  1.0  0.2  1.0  0.9  0.3  0.4  0.9  0.2   0.5
 [3,]  0.6  0.2  0.8  0.3  0.6  0.9  0.4  0.5   NA   0.8
 [4,]  0.2  0.4  0.9  0.5  0.3  0.4  0.6  0.1  0.9   0.2
 [5,]  0.9  0.1  0.5  0.8  0.9  0.6  0.5  0.1  0.2   0.4
 [6,]  0.9  0.7  0.6  0.0  0.4  0.4  0.2  0.0  0.8   0.2
 [7,]   NA  0.4  0.8  0.0  0.4  0.7  0.4  0.7  0.6   0.3
 [8,]  0.8  0.8  0.3  0.7  0.5  0.0  0.1  0.4  0.3   0.6
 [9,]  0.5  0.2  0.7   NA  0.2  0.4  0.1   NA  0.7   0.3
[10,]  0.5   NA  0.2  0.3  0.1  0.2  0.4  0.8  0.3    NA
[11,]  0.6  0.5   NA  0.8  0.3  0.9  0.2  0.8  0.2   0.7
[12,]   NA  0.1   NA  0.8  0.3  1.0  0.4  0.9   NA   0.7
[13,]  0.8   NA  0.1   NA  0.0  0.3  1.0   NA  0.0   0.3
[14,]  0.2  1.0  0.2  0.6  0.2  0.7   NA  1.0   NA   0.5
[15,]  0.4  0.1  0.9  0.7  0.2  0.3  0.3  0.6  0.3   0.3

如您所见,第5列和第6列没有NAs。

现在,让我们创建一个类似的矩阵,其中NAs为0,非NA为1。

is_na_vector<- ifelse(is.na(x),0,1)

之后,让我们计算 crossproduct
crossprod_vector <- crossprod(is_na_vector)
colSums(crossprod_vector)
 [1] 119 120 119 120 135 135 127 120 111 127

正如您所看到的,第5列和第6列具有最高的colSums。这意味着它们与其他变量相结合,具有最少的NAs。

然后,我们使用该colSums向量选择多个列。这将对所有列进行排名,并给出前n个。以下是具有最大非NA行数的三列。在这种情况下,为14行。此时可能会存在并列,但在选择20列时不应该成为问题。

n <- 3
x_df <- as.data.frame(x) #to get meaningful colnames
res <- x_df[,rank(-colSums(crossprod_vector),ties.method ="first")<=n ] #use "-" to get decreasing rank
res
          V5        V6        V7
1  0.7700279 0.7554624 0.9767552
2  0.8869842 0.2880597 0.3970164
3  0.6251217 0.8678447 0.3799989
4  0.2603000 0.4026427 0.5603876
5  0.8590731 0.5726850 0.4638082
6  0.4374880 0.3506426 0.1967768
7  0.3881448 0.6719989 0.4269434
8  0.4615011 0.0250504 0.0930252
9  0.2186752 0.4011010 0.1153091
10 0.0659355 0.1999765 0.4400317
11 0.2757010 0.8565250 0.2009347
12 0.3103811 0.9715154 0.4276391
13 0.0421755 0.3237224 0.9806000
14 0.1846735 0.7331914        NA
15 0.1833732 0.3400682 0.2869739

使用na.omit获取非NA行:
na.omit(res)
          V5        V6        V7
1  0.7700279 0.7554624 0.9767552
2  0.8869842 0.2880597 0.3970164
3  0.6251217 0.8678447 0.3799989
4  0.2603000 0.4026427 0.5603876
5  0.8590731 0.5726850 0.4638082
6  0.4374880 0.3506426 0.1967768
7  0.3881448 0.6719989 0.4269434
8  0.4615011 0.0250504 0.0930252
9  0.2186752 0.4011010 0.1153091
10 0.0659355 0.1999765 0.4400317
11 0.2757010 0.8565250 0.2009347
12 0.3103811 0.9715154 0.4276391
13 0.0421755 0.3237224 0.9806000
15 0.1833732 0.3400682 0.2869739

你可以使用 nrow 函数来查看非 NA 行的数量:
nrow(na.omit(res)) #14

"

对于 n <- 5,我得到了12行非NA值

"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接