让我有一个具有缺失值(NA)的数据帧(df)
DF:
head1 head2 head3 head4 head5
----- ----- ----- ----- -----
65 25 12 65 76
78 5 NA 12 NA
NA NA 12 5 51
76 32 6 94 11
67 32 NA 1 NA
我想创建一个列表(list1),每个元素由具有相同NA模式的数据帧组成。
对于这个例子:
如何使用R创建这样的列表?我会很高兴得到任何帮助。非常感谢。
@akrun,我意识到你的代码适用于NA列不是每列常见的数据帧。但不适用于以下数据框架。
df1<-data.frame(head1=c(65,78,NA,76,67),
head2=c(25,5,NA,32,32),
head3=c(12,12,NA,6,NA),
head4=c(65,12,5,94,1),
head5=c(76,NA,51,11,NA)
)
i1 <- which(is.na(df1), arr.ind=TRUE)
l1 <- unique(split(i1[,2], i1[,1]))
i2 <- c(l1, setdiff(seq_along(df1), unlist(l1)))
l2 <- lapply(i2, function(i) df1[i])
l2[order(sapply(l2, function(x) colnames(x)[1]))]
结果是:
[[1]]
head1 head2 head3
1 65 25 12
2 78 5 12
3 NA NA NA
4 76 32 6
5 67 32 NA
[[2]]
head3 head5
1 12 76
2 12 NA
3 NA 51
4 6 11
5 NA NA
[[3]]
head4
1 65
2 12
3 5
4 94
5 1
[[4]]
head5
1 76
2 NA
3 51
4 11
5 NA
答案 0 :(得分:1)
我们使用which
获取NA元素的行/列索引并指定arr.ind=TRUE
。我们split
&#34; col&#34;通过&#34; row&#34;,获取索引的unique
元素,如果有一些列缺失,即没有NA值,我们可以连接(c
)到结尾list
。然后,subset
数据集使用索引循环list
(lapply(i2,..
),我们可以order
输出list
(&#39; l2& #39;)按每个list
元素中的第一个列名称。
i1 <- which(is.na(df1), arr.ind=TRUE)
l1 <- unique(split(i1[,2], i1[,1]))
i2 <- c(l1, setdiff(seq_along(df1), unlist(l1)))
l2 <- lapply(i2, function(i) df1[i])
l2[order(sapply(l2, function(x) colnames(x)[1]))]
#[[1]]
# head1 head2
#1 65 25
#2 78 5
#3 NA NA
#4 76 32
#5 67 32
#[[2]]
# head3 head5
#1 12 76
#2 NA NA
#3 12 51
#4 6 11
#5 NA NA
#[[3]]
# head4
#1 65
#2 12
#3 5
#4 94
#5 1
答案 1 :(得分:1)
使用每列中的NA
值索引,您可以将每列映射为“字符”值:
map = sapply(df1, function(X) paste(which(is.na(X)), collapse = ";"))
map
#head1 head2 head3 head4 head5
# "3" "3" "3;5" "" "2;5"
然后,相应地split
列:
split.default(df1, match(map, unique(map)))
#> str(.Last.value)
#List of 4
# $ 1:'data.frame': 5 obs. of 2 variables:
# ..$ head1: num [1:5] 65 78 NA 76 67
# ..$ head2: num [1:5] 25 5 NA 32 32
# $ 2:'data.frame': 5 obs. of 1 variable:
# ..$ head3: num [1:5] 12 12 NA 6 NA
# $ 3:'data.frame': 5 obs. of 1 variable:
# ..$ head4: num [1:5] 65 12 5 94 1
# $ 4:'data.frame': 5 obs. of 1 variable:
# ..$ head5: num [1:5] 76 NA 51 11 NA
对于实际尺寸的数据,性能似乎是可以忍受的:
set.seed(666)
DF = as.data.frame(matrix(sample(c(NA, 1:10), 115000 * 100, TRUE), 115000, 100))
DF = DF[, sample(ncol(DF), 140, TRUE)]
system.time({
map = sapply(DF, function(X) paste(which(is.na(X)), collapse = ";"))
split.default(DF, match(map, unique(map)))
})
# user system elapsed
# 1.64 0.00 1.67
...除非每列中有~60%NA
个:
set.seed(911)
DF2 = as.data.frame(replicate(100, sample(c(NA, 1:2), 115000, TRUE, c(0.6, 0.2, 0.2)), simplify = FALSE))
DF2 = DF2[, sample(ncol(DF2), 140, TRUE)]
system.time({
map = sapply(DF2, function(X) paste(which(is.na(X)), collapse = ";"))
split.default(DF2, match(map, unique(map)))
})
# user system elapsed
# 8.70 0.09 8.99