【问题标题】:Swap NA's with values whilst preserving original value order用值交换 NA,同时保留原始值顺序
【发布时间】:2018-01-31 12:05:45
【问题描述】:

考虑一个有序数据框,其列由值和 NA 组成,如下所示:

df <- data.frame(id=rep(1:6), value=c(NA,NA,23,45,12,76))

我想将 NA 的位置转移到数据框的前两行,同时保持值的顺序如下:

df$new_value <- c(23,45,12,76,NA,NA)

无论如何我可以做到这一点吗?谢谢!

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我们可以在NA 元素上使用order

    df$new_value <- df$value[order(is.na(df$value))]
    df$new_value
    #[1] 23 45 12 76 NA NA
    

    通过is.na,它返回一个逻辑向量

     is.na(df$value)
     #[1]  TRUE  TRUE FALSE FALSE FALSE FALSE
    

    在其上应用order 会返回

    order(is.na(df$value))
    #[1] 3 4 5 6 1 2
    

    因为FALSE 按字母顺序排列在TRUE 之前。 order 值是向量的初始位置索引。这可以更容易理解

    sort(c(TRUE, FALSE, TRUE), index.return = TRUE)
    #$x
    #[1] FALSE  TRUE  TRUE
    
    #$ix
    #[1] 2 1 3
    

    【讨论】:

      【解决方案2】:

      另一个仅当您的 NA 位于数据帧的最末端才有效的想法是使用 dplyr 中的 lead 函数来将您的数据 n 位置向前移动。所以对于你的情况,它会是,

      dplyr::lead(df$value, sum(is.na(df$value)))
      #[1] 23 45 12 76 NA NA
      

      【讨论】:

      • 谢谢! dplyr 解决方案更适合我的需求,但是,您的解决方案似乎不适用于 group_by,例如:df &lt;- data.frame(fact=c(1,1,1,2,2,2), id=rep(1:6), value=c(NA,44,23,NA,NA,76)) df &lt;- df %&gt;% group_by(fact) %&gt;% mutate(newvar = dplyr::lead(df$value, sum(is.na(df$value))))
      【解决方案3】:

      如果不聪明,也可以应用一些基本技术:

      df$new_value <- c(df[!is.na(df$value), "value"], df[is.na(df$value), "value"])
      
        id value new_value
      1  1    NA        23
      2  2    NA        45
      3  3    23        12
      4  4    45        76
      5  5    12        NA
      6  6    76        NA
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-04
        • 2020-01-13
        • 2016-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多