[英]Grouping columns with same missing value patterns in R
讓我有這樣一個缺失值的數據幀(df)(NA)
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
我們得到NA元素的行/列索引which
並指定arr.ind=TRUE
。 我們split
“col” split
為“row”,獲取索引的unique
元素,如果缺少某些列,即沒有NA值,我們可以將( c
)連接到list
的末尾。 然后,通過循環遍歷list
( lapply(i2,..
))使用索引對數據集進行subset
集化,並且我們可以order
每個list
元素中的第一列名稱對輸出list
('l2')進行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
使用每列中的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.