R:有什么方法可以从数据帧中的每一列发送所有 NA 吗?

R: Is there any way to send down all the NAs from each column in a dataframe?

给定如下所示的数据框:

farm_1       farm_2        farm_3
NA           chicken       NA
cow          lamb          NA
NA           NA            deer
lamb         pig           pig
NA           donkey        NA

我想重塑它,使每一列包含的所有 NA 都转到较低的位置,而将较高的保留为实际值。因此,示例中的数据框应该变成这样:

farm_1       farm_2        farm_3
cow          chicken       deer
lamb         lamb          pig
NA           pig           NA
NA           donkey        NA
NA           NA            NA

为了它的好处。实现所需结果的 tidyverse 方法可能如下所示:

d <- read.table(text = "farm_1       farm_2        farm_3
NA           chicken       NA
cow          lamb          NA
NA           NA            deer
lamb         pig           pig
NA           donkey        NA", header = TRUE)

library(dplyr)

mutate(d, across(everything(), sort, na.last = TRUE))
#>   farm_1  farm_2 farm_3
#> 1    cow chicken   deer
#> 2   lamb  donkey    pig
#> 3   <NA>    lamb   <NA>
#> 4   <NA>     pig   <NA>
#> 5   <NA>    <NA>   <NA>

如果你想保留非 NA 值的顺序(感谢@Lucas 指出)你可以这样做:

mutate(d, across(everything(), ~ sort(forcats::fct_inorder(.x), na.last = TRUE)))
#>   farm_1  farm_2 farm_3
#> 1    cow chicken   deer
#> 2   lamb    lamb    pig
#> 3   <NA>     pig   <NA>
#> 4   <NA>  donkey   <NA>
#> 5   <NA>    <NA>   <NA>

您可以使用 na.omit 删除 NA 值,对值进行子集化,以便最后的值附加 NA

df[] <- lapply(df, function(x) na.omit(x)[1:length(x)])

#  farm_1  farm_2 farm_3
#1    cow chicken   deer
#2   lamb    lamb    pig
#3   <NA>     pig   <NA>
#4   <NA>  donkey   <NA>
#5   <NA>    <NA>   <NA>

或者如果你喜欢 dplyr -

library(dplyr)
df %>% mutate(across(.fns = ~na.omit(.)[1:length(.)]))