【问题标题】:sum() condition in ifelse statementifelse 语句中的 sum() 条件
【发布时间】:2021-11-27 01:55:00
【问题描述】:

这个问题和这个问题有关My question is about R: How to number each repetition in a table in R?

基本上重复的地方都有编号。例如两次重复: 1,2 ;三个重复:1,2,3 等...但是如果该值是唯一的(只有一次),则它应该不是1,而是NA

数据:(来自 akrun,非常感谢!)

df1 <- structure(list(Fullname = c("Peter", "Peter", "Alison", "Warren", 
                                   "Jack", "Jack", "Jack", "Jack", "Susan", "Susan", "Henry", "Walison", 
                                   "Tinder", "Peter", "Henry", "Tinder")), row.names = c(NA, -16L
                                   ), class = "data.frame")

我的解决方案是这样的:

df1 %>% 
  group_by(Fullname) %>% 
  mutate(newcol = seq_along(Fullname)) 

  Fullname newcol
   <chr>     <int>
 1 Peter         1
 2 Peter         2
 3 Alison        1
 4 Warren        1
 5 Jack          1
 6 Jack          2
 7 Jack          3
 8 Jack          4
 9 Susan         1
10 Susan         2
11 Henry         1
12 Walison       1
13 Tinder        1
14 Peter         3
15 Henry         2
16 Tinder        2

现在我尝试将每个出现一次的值(例如 Alison、Warren 和 Henry)设置为 NA就像 akrun 在这里所做的 My question is about R: How to number each repetition in a table in R?

我的代码使用ifelse 语句检查组的总和是否>1。

df1 %>% 
  group_by(Fullname) %>% 
  mutate(newcol = seq_along(Fullname)) %>% 
  mutate(newcol = ifelse(sum(newcol)>1, newcol, NA))

但我明白了:

 Fullname newcol
   <chr>     <int>
 1 Peter         1
 2 Peter         1
 3 Alison       NA
 4 Warren       NA
 5 Jack          1
 6 Jack          1
 7 Jack          1
 8 Jack          1
 9 Susan         1
10 Susan         1
11 Henry         1
12 Walison      NA
13 Tinder        1
14 Peter         1
15 Henry         1
16 Tinder        1

我不明白为什么?

【问题讨论】:

    标签: r if-statement dplyr sum


    【解决方案1】:

    前提是您已经了解错误发生的原因。然而,我认为sum 不是在这里使用的正确功能。是的,你可以让它工作,但它看起来很复杂。您可以使用n() 获取组中的行数并使用if 条件进行检查。

    library(dplyr)
    
    df1 %>%
      group_by(Fullname) %>%
      mutate(newcol = if(n() == 1) NA else row_number()) %>%
      ungroup
    
    # Fullname newcol
    #   <chr>     <int>
    # 1 Peter         1
    # 2 Peter         2
    # 3 Alison       NA
    # 4 Warren       NA
    # 5 Jack          1
    # 6 Jack          2
    # 7 Jack          3
    # 8 Jack          4
    # 9 Susan         1
    #10 Susan         2
    #11 Henry         1
    #12 Walison      NA
    #13 Tinder        1
    #14 Peter         3
    #15 Henry         2
    #16 Tinder        2
    

    【讨论】:

      【解决方案2】:

      这里我们需要if/else 而不是ifelse,因为ifelse 要求所有参数的长度相同,sum 返回单个值,如果是TRUE,则全部为真

      library(dplyr)
      df1 %>% 
        group_by(Fullname) %>% 
        mutate(newcol = row_number(), 
             newcol = if(sum(newcol)> 1) newcol else NA) %>%
        ungroup
      

      -输出

      # A tibble: 16 × 2
         Fullname newcol
         <chr>     <int>
       1 Peter         1
       2 Peter         2
       3 Alison       NA
       4 Warren       NA
       5 Jack          1
       6 Jack          2
       7 Jack          3
       8 Jack          4
       9 Susan         1
      10 Susan         2
      11 Henry         1
      12 Walison      NA
      13 Tinder        1
      14 Peter         3
      15 Henry         2
      16 Tinder        2
      

      现在,我们来看看这个问题。 'newcol2' 值是单个 TRUE/FALSE 的回收值。在ifelse 中,由于所有参数的长度必须相同,因此逻辑部分的长度仅为 1。

      df1 %>% 
         group_by(Fullname) %>% 
         mutate(newcol = row_number(), newcol2 = sum(newcol) > 1)
      # A tibble: 16 × 3
      # Groups:   Fullname [8]
         Fullname newcol newcol2
         <chr>     <int> <lgl>  
       1 Peter         1 TRUE   
       2 Peter         2 TRUE   
       3 Alison        1 FALSE  
       4 Warren        1 FALSE  
       5 Jack          1 TRUE   
       6 Jack          2 TRUE   
       7 Jack          3 TRUE   
       8 Jack          4 TRUE   
       9 Susan         1 TRUE   
      10 Susan         2 TRUE   
      11 Henry         1 TRUE   
      12 Walison       1 FALSE  
      13 Tinder        1 TRUE   
      14 Peter         3 TRUE   
      15 Henry         2 TRUE   
      16 Tinder        2 TRUE  
      

      解决方法是replicate 让长度一致

      df1 %>% 
        group_by(Fullname) %>% 
        mutate(newcol = seq_along(Fullname)) %>% 
        mutate(newcol = ifelse(rep(sum(newcol)>1, n()), newcol, NA))
      # A tibble: 16 × 2
      # Groups:   Fullname [8]
         Fullname newcol
         <chr>     <int>
       1 Peter         1
       2 Peter         2
       3 Alison       NA
       4 Warren       NA
       5 Jack          1
       6 Jack          2
       7 Jack          3
       8 Jack          4
       9 Susan         1
      10 Susan         2
      11 Henry         1
      12 Walison      NA
      13 Tinder        1
      14 Peter         3
      15 Henry         2
      16 Tinder        2
      

      为了更好的理解,只取一个简单的向量

      > v1 <- c(1:5)
      > sum(v1) > 4
      [1] TRUE
      > ifelse(sum(v1) > 4, v1, NA)
      [1] 1
      

      这里的sum 是15,肯定大于4。一旦找到TRUE,它只返回向量的第一个元素,即1,然后停止。在%&gt;% 中也是这样,但是因为有回收,所以 1 被重复以填满整个组

      【讨论】:

      • @TarJae 我添加了一些解释。希望对你有帮助
      • 这确实有帮助。你刚刚在我对 R 编程的理解中又缩小了一个差距!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多