【问题标题】:sum the column values(group_by) keeping NA values and not replacing with zero in R对列值(group_by)求和,保持 NA 值,而不是用 R 中的零替换
【发布时间】:2020-04-17 03:47:08
【问题描述】:

我正在尝试按另一列对列值分组求和,我需要保留 NA 值,我不应该用零替换值,因为基于总和,如果总和为 NA,我必须给出排名,排名应该为空。

以下是理解问题的示例

column1column2column3

10 英镑

b gb 不适用

c gb 不适用

d gb 4

e Hs 81

b Hs 不适用

c Hs 2

不适用的路

x Rd NA

z Rd NA

我必须按 column2 对 column3 值进行求和,并且在进行求和时,我不应该考虑 NA 值并将该组的其他值相加,我不应该删除或用零替换 NA 值。基于这个总和,如果总和为 NA(参考组 Rd),我必须给出排名,那么将没有排名。我可以用零替换 NA 值,但我必须在 sum 之后给出排名,如果 sum 为 NA,排名将为空(如果是上述数据中的组 Rd)。对于 gb 组,总和值为 14,Hs 组总和值为 83,Rd 组总和值为 NA,在这种情况下,该组将没有排名。

下面是我试过的代码sn-p

df %>% group_by_at(column2) %>% summarise(sum = sum(column3, na.rm = TRUE))

上面的代码通过将所有 NA 替换为零来求和值,但我不想替换。我需要 NA 给予排名。你能提供任何解决方案吗?

预期输出:

column2 column3 排名

GB 14 2

Hs 83 1

Rd NA 无等级

【问题讨论】:

  • 预期输出应该类似于 column2 column3 rank gb 14 2 Hs 83 1 Rd NA No Rank
  • 你能检查一下我的解决方案吗

标签: r


【解决方案1】:

您可以使用rankna.last = "keep"rank 指定为NA

library(dplyr)

df %>% 
  group_by(column2) %>% 
  summarise(column3 = if(all(is.na(column3))) NA else 
                         sum(column3, na.rm = TRUE)) %>%
  ungroup %>%
  mutate(rank = rank(-column3, na.last = "keep"))

#  column2 column3  rank
#  <fct>     <int> <dbl>
#1 gb           14     2
#2 Hs           83     1
#3 Rd           NA    NA

【讨论】:

  • 第 3 列数据中也会有零以及 NA
  • @嗯好吧。更新了答案。
【解决方案2】:

我们可以使用hablar中的sum_,如果所有值都是NA,则返回NA,然后使用dense_rank

library(dplyr)
library(hablar)
df %>% 
  group_by(column2) %>% 
  summarise(column3 = sum_(column3))  %>%
  mutate(rank = dense_rank(-column3))
# A tibble: 3 x 3
#  column2 column3  rank
#  <chr>     <int> <int>
#1 gb           14     2
#2 Hs           83     1
#3 Rd           NA    NA

或使用data.table

library(data.table)
setDT(df)[, .(column3 = sum_(column3)), column2][, 
       rank := frank(-column3, na.last = 'keep')][]

数据

df <- structure(list(column1 = c("a", "b", "c", "d", "e", "b", "c", 
"a", "x", "z"), column2 = c("gb", "gb", "gb", "gb", "Hs", "Hs", 
"Hs", "Rd", "Rd", "Rd"), column3 = c(10L, NA, NA, 4L, 81L, NA, 
2L, NA, NA, NA)), class = "data.frame", row.names = c(NA, -10L
))

【讨论】:

    【解决方案3】:

    基础 R 解决方案:

    within(aggregate(column3~column2, df, FUN = function(x){
        ifelse(all(is.na(x)), NA_integer_, sum(x, na.rm = TRUE))}, 
        na.action = na.pass), {rank = ifelse(is.na(column3), NA_integer_,
                                             rank(-column3))})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-12-31
      • 2015-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多