【问题标题】:group_by and pmap a piecewise operation on each row per group (ifelse vs case_when)group_by 和 pmap 对每组的每一行进行分段操作(ifelse vs case_when)
【发布时间】:2021-01-14 13:19:56
【问题描述】:

我正在尝试对一个变量进行分组,然后对每组的每行进行操作。我在使用 ifelse vs case_when 时迷路了。在两者的用法之间,我无法理解一些基本的东西。我假设两者都会给我相同的输出,但这里不是这种情况。使用 ifelse 没有给出预期的输出,但是 case_when 给出了。我试图理解为什么 ifelse 没有给我预期的输出。

这里是例子 df

structure(list(Pos = c(73L, 146L, 146L, 150L, 150L, 151L, 151L, 
152L, 182L, 182L), Percentage = c(81.2, 13.5, 86.4, 66.1, 33.9, 
48.1, 51.9, 86.1, 48, 52)), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame")) -> foo

我按 Pos 分组,如果它们的总和为 100,我想四舍五入 Percentage。以下是使用 ifelse:

library(tidyverse)
foo %>% 
     group_by(Pos) %>%
     mutate(sumn = n()) %>% 
     mutate(Val = ifelse(sumn == 1,100,
                         ifelse(sum(Percentage) == 100, unlist(map(Percentage,round)), 0)
                         # case_when(sum(Percentage) == 100 ~ unlist(map(Percentage,round)),
                         #           TRUE ~ 0
                         # )
                         ))

输出是

# A tibble: 10 x 4
# Groups:   Pos [6]
     Pos Percentage  sumn   Val
   <int>      <dbl> <int> <dbl>
 1    73       81.2     1   100
 2   146       13.5     2     0
 3   146       86.4     2     0
 4   150       66.1     2    66
 5   150       33.9     2    66
 6   151       48.1     2    48
 7   151       51.9     2    48
 8   152       86.1     1   100
 9   182       48       2    48
10   182       52       2    48

我不想要这个,而是想要使用 case_when 得到的以下内容

   foo %>% 
     group_by(Pos) %>%
     mutate(sumn = n()) %>% 
     mutate(Val = ifelse(sumn == 1,100,
                         #ifelse(sum(Percentage) == 100, unlist(map(Percentage,round)), 0)
                         case_when(sum(Percentage) == 100 ~ unlist(map(Percentage,round)),
                                   TRUE ~ 0
                         )
                         ))

# A tibble: 10 x 4
# Groups:   Pos [6]
     Pos Percentage  sumn   Val
   <int>      <dbl> <int> <dbl>
 1    73       81.2     1   100
 2   146       13.5     2     0
 3   146       86.4     2     0
 4   150       66.1     2    66
 5   150       33.9     2    34
 6   151       48.1     2    48
 7   151       51.9     2    52
 8   152       86.1     1   100
 9   182       48       2    48
10   182       52       2    52

ifelse 有什么不同?

【问题讨论】:

  • sum(Percentage) 是一个单一的值,它正在被回收。我猜你需要if/else
  • 使用 ifelse 它正在被回收,但 case_when 工作正常。为什么 ifelse 会回收它而 case_when 不呢?
  • case_when 也回收,但Both LHS and RHS may have the same length of either 1 or n. The value of n must be consistent across all cases

标签: r dplyr


【解决方案1】:

根据?ifelse

长度和属性(包括维度和“类”)与来自 yes 或 no 值的测试和数据值相同的向量。

如果我们复制以使长度相同,那么它应该可以工作

foo %>% 
      group_by(Pos) %>%
      mutate(sumn = n()) %>% 
      mutate(Val = ifelse(sumn == 1,100,
                          ifelse(rep(sum(Percentage) == 100, 
                      n()), unlist(map(Percentage,round)), 0)                            
                          ))
# A tibble: 10 x 4
# Groups:   Pos [6]
     Pos Percentage  sumn   Val
   <int>      <dbl> <int> <dbl>
 1    73       81.2     1   100
 2   146       13.5     2     0
 3   146       86.4     2     0
 4   150       66.1     2    66
 5   150       33.9     2    34
 6   151       48.1     2    48
 7   151       51.9     2    52
 8   152       86.1     1   100
 9   182       48       2    48
10   182       52       2    52

【讨论】:

    猜你喜欢
    • 2014-08-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2018-02-26
    • 1970-01-01
    • 1970-01-01
    • 2018-10-14
    • 1970-01-01
    相关资源
    最近更新 更多