我正在寻找一种简单的方法将至少有一个NA的所有行移动到dataframe/datatable的底部.例如 :
> df <- data.table(aaa=c(1,2,3,4,NA,6,7),
bbb=c(1,9,5,NA,3,NA,9),
ccc=c(NA,3,NA,4,8,NA,2)
)
> df
aaa bbb ccc
1: 1 1 NA
2: 2 9 3
3: 3 5 NA
4: 4 NA 4
5: NA 3 8
6: 6 NA NA
7: 7 9 2
Run Code Online (Sandbox Code Playgroud)
会变成这样的:
> df2 <- moveNAtoBottom(df)
> df2
aaa bbb ccc
1: 2 9 3
2: 7 9 2
3: 1 1 NA
4: 3 5 NA
5: 4 NA 4
6: NA 3 8
7: 6 NA NA
Run Code Online (Sandbox Code Playgroud)
即所有列顶部没有NA.
备注:
更好的是,如果我能够指定必须应用搜索NA的列.例如,仍然使用前面的示例:
> df3 <- moveNAtoBottom(df, applyTo = c("bbb", "ccc"))
> df3
aaa bbb ccc
1: 2 9 3
2: NA 3 8
3: 7 9 2
4: 1 1 NA
5: 3 5 NA
6: 4 NA 4
7: 6 NA NA
Run Code Online (Sandbox Code Playgroud)
谢谢
你可以这样做:
library(dplyr)
df %>%
arrange(rowSums(is.na(.)))
Run Code Online (Sandbox Code Playgroud)
这使:
# aaa bbb ccc
#1 2 9 3
#2 7 9 2
#3 1 1 NA
#4 3 5 NA
#5 4 NA 4
#6 NA 3 8
#7 6 NA NA
Run Code Online (Sandbox Code Playgroud)
或者您是否要指定列名称:
df %>%
arrange(rowSums(is.na(select_(., 'bbb:ccc'))))
Run Code Online (Sandbox Code Playgroud)
这使:
# aaa bbb ccc
#1 2 9 3
#2 NA 3 8
#3 7 9 2
#4 1 1 NA
#5 3 5 NA
#6 4 NA 4
#7 6 NA NA
Run Code Online (Sandbox Code Playgroud)
当使用OP时data.table,一个选项data.table是循环遍历列lapply,检查它是否为NA(is.na),得到行方式和Reduce,并将其用于order'df'行.
df[order(Reduce(`+`, lapply(df, is.na)))]
# aaa bbb ccc
#1: 2 9 3
#2: 7 9 2
#3: 1 1 NA
#4: 3 5 NA
#5: 4 NA 4
#6: NA 3 8
#7: 6 NA NA
Run Code Online (Sandbox Code Playgroud)
这是一个类似的方法:
df[, anyna := FALSE]
for (k in names(df)) df[!(anyna), anyna := is.na(get(k))]
df[order(anyna)][, anyna := NULL][]
Run Code Online (Sandbox Code Playgroud)