我问了同样的问题 here,但它已关闭,因为我的帖子与类似问题相关尽管它们与我的问题无关,也没有解决。 >
数据集:
我有一个巨大的数据集保存在一个矩阵中,其中的行数超过一百万,有十几个列。
矩阵看起来像
data <- matrix(c(1, NA, 2, NA, 1, NA, NA, NA, 1, NA, 3, NA, 5, NA, NA, NA, 8, NA, 5, NA, 7, NA, NA, NA), ncol=3)
> data
[,1] [,2] [,3]
[1,] 1 1 8
[2,] NA NA NA
[3,] 2 3 5
[4,] NA NA NA
[5,] 1 5 7
[6,] NA NA NA
[7,] NA NA NA
[8,] NA NA NA
因此,如果某列中存在缺失值,那么必然其他列的同一行中也会存在缺失值。
问题:
如果矩阵中所有列的每列中有 3 个或更多,我想“有效地” 删除连续缺失值。所以我想删除一列而不是一行中的连续 na。
对于我的问题,我已经看到了解决方案,例如 this one,但是对于我的庞大数据集来说它们太慢了。您还有其他可以有效实现目标的建议吗?此外,如果缺失值在行而非列中是连续的,则我的封闭问题的建议答案(1 和 2)将被删除。
编辑:
根据下面的注释,输出必须是这样的:
[,1] [,2] [,3]
[1,] 1 1 8
[2,] NA NA NA
[3,] 2 3 5
[4,] NA NA NA
[5,] 1 5 7
编辑:
> data
[,1] [,2] [,3] [,4]
[1,] 1 1 8 NA
[2,] NA NA NA NA
[3,] 2 3 5 NA
[4,] NA NA NA NA
[5,] 1 5 7 NA
[6,] NA NA NA NA
[7,] NA NA NA NA
[8,] NA NA NA NA
预期输出
[,1] [,2] [,3]
[1,] 1 1 8
[2,] NA NA NA
[3,] 2 3 5
[4,] NA NA NA
[5,] 1 5 7
答案 0 :(得分:2)
如果是连续的,那么可能是rle
可以使用
i1 <- rowSums(is.na(data)) > 0
# // or just forgot to update here
i1 <- is.na(data[,1])
data[!inverse.rle(within.list(rle(i1), {
values[values & lengths < 3] <- FALSE})),]
-输出
# [,1] [,2] [,3]
#[1,] 1 1 8
#[2,] NA NA NA
#[3,] 2 3 5
#[4,] NA NA NA
#[5,] 1 5 7
如果我们有一个包含所有 NA
的特定列,那么我们可以先将其删除
data1 <- data[,colSums(!is.na(data)) != 0]
现在我们将前面的代码应用于选定的列数据
i1 <- is.na(data1[,1])
data1[!inverse.rle(within.list(rle(i1), {
values[values & lengths < 3] <- FALSE})),]
或者我们可以使用 rleid
中的 data.table
(这样效率更高)
library(data.table)
data[as.data.table(data)[, .I[!(.N >=3 & is.na(V1))],
rleid(is.na(V1))]$V1,]
答案 1 :(得分:2)
如果某列中存在缺失值,那么必然其他列的同一行也存在缺失值。
我认为这是非常重要的信息,我们可以利用它并且只处理任何 1 列而不是完整的数据集。试试:
vec <- data[, 1]
data[!with(rle(is.na(vec)), rep(values & lengths >= 3, lengths)), ]
# [,1] [,2] [,3]
#[1,] 1 1 8
#[2,] NA NA NA
#[3,] 2 3 5
#[4,] NA NA NA
#[5,] 1 5 7