【问题标题】:Put all the missing values to the right side of data frame [duplicate]将所有缺失值放在数据框的右侧[重复]
【发布时间】:2021-08-17 12:55:42
【问题描述】:

我的数据框(数据表)中有很多缺失的数据,我需要将它们全部移到右侧。有什么方法可以做到吗?

样本数据

as.data.table(structure(list(`1` = c(NA_integer_, NA_integer_), `2` = c(NA, 
1L), `3` = c(1L, 1L), `4` = c(0L, NA), `5` = c(NA_integer_, NA_integer_
)), row.names = c(NA, -2L), class = c("data.table", "data.frame"
)))

预期的输出如下,

1, 0, NA, NA, NA
1, 1, NA, NA, NA

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    更新我只是做了一些修改,以便我们有一个有序的列名,但它可以更改。

    您可以使用以下解决方案。也许有一种更简单的方法,但现在我可以想到这个:

    library(dplyr)
    library(purrr)
    
    df %>%
      pmap(., ~ c(c(...)[!is.na(c(...))], c(...)[is.na(c(...))])) %>%
      exec(rbind, !!!.) %>%
      as_tibble() %>%
      set_names(1:length(.))
    
    # A tibble: 2 x 5
        `1`   `2`   `3`   `4`   `5`
      <int> <int> <int> <int> <int>
    1     1     0    NA    NA    NA
    2     1     1    NA    NA    NA
    

    【讨论】:

      【解决方案2】:

      因为它是一个data.table 对象,

      library(data.table)
      dcast(melt(copy(DT)[, rn := seq_len(.N)], "rn"
                )[, variable := as.character(rank(is.na(value), ties="first")), by = rn],
            rn ~ variable, value.var = "value")[, rn := NULL][]
      #        1     2     3     4     5
      #    <int> <int> <int> <int> <int>
      # 1:     1     0    NA    NA    NA
      # 2:     1     1    NA    NA    NA
      

      或者也许是一种效率较低的方法:

      DT[] <- as.data.table(t(apply(DT, 1, function(z) z[order(is.na(z))])))
      DT
      #        1     2     3     4     5
      #    <int> <int> <int> <int> <int>
      # 1:     1     0    NA    NA    NA
      # 2:     1     1    NA    NA    NA
      

      仅供参考,从某种意义上说,您打破了data.frame-结构的前提,其中列是字段/属性;像这样在列之间移动值表明(a)数据确实属于长格式(使用melt)并保持这种方式,或者(b)您应该处理matrix。也许它比我们看到的要多得多,只是一个想法。

      【讨论】:

      • 亲爱的@r2evans,您对从哪里开始学习data.table 有什么建议吗?因为我完全不熟悉它。我会很感激任何建议。
      • 老实说,一个好的开始是它的网页rdatatable.gitlab.io/data.table 及其所有vignettes。从那里开始,我强迫自己开始在一些小型个人项目中使用它,然后开始在 SO 上查看问题并尝试回答它们。由于作者/维护者和许多非常聪明的data.table 人通常会用答案击败我,我从他们的评论中学到了东西。这是一场艰苦的战斗(真的是一种不同的 R 方言),但事情只是在某个时候开始“变得有意义”。
      • 我做的一件事是维护一个翻译列表(各种),说明如何在基础 R、dplyr(和 tidyr)、data.table 和 python pandas 中做事;虽然这不是我保持最新或准备公开的内容,但只是制作我自己的参考指南确实有助于理解我想要从data.table 得到什么。还有很多方面我没有处理,但我现在对重塑、基本分组、非等值连接以及它的一些内部功能效率相当满意。
      • 非常感谢您的鼓励 cmets 以及链接。是的,你是对的,我也发现 SO 是一个很好的学习来源,因为在过去的三个月里,我以与你提到的相同的方式学到了很多东西。 SO 有一些很棒的 data.table 用户,就像你自己一样。真的非常感谢。
      • 我完全理解。这一次,你对要寻找什么和学习什么有了更清晰的认识。我认为当你开始学习一门新的编程语言时也是如此(尽管我还没有)。我看到了一些基准测试尝试,并惊讶地发现pandas 也更快。
      【解决方案3】:

      Repeating pmap 答案,但这不会改变您在输出中的姓名序列

      pmap_dfr(dt, ~c(c(...)[!is.na(c(...))], rep(NA, sum(is.na(c(...))))) %>%
                 setNames(names(c(...))))
      
      # A tibble: 2 x 5
          `1`   `2`   `3`   `4`   `5`
        <int> <int> <int> <int> <int>
      1     1     0    NA    NA    NA
      2     1     1    NA    NA    NA
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-15
        • 1970-01-01
        • 2022-11-18
        • 2021-02-06
        • 1970-01-01
        • 2019-01-09
        • 2016-09-01
        • 1970-01-01
        相关资源
        最近更新 更多