首页 > 解决方案 > ifelse 语句中的 sum() 条件

问题描述

这个问题与这个问题有关我的问题是关于R:如何在R中的表格中对每个重复进行编号?

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

数据:(来自 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

现在我尝试将每个出现一次的值(例如艾莉森、沃伦和亨利)设置为NA喜欢 akrun 在这里所做的我的问题是关于 R:如何在 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

我不明白为什么?

标签: rif-statementdplyrsum

解决方案


我们需要if/else在这里而不是ifelse要求ifelse所有参数的长度相同,sum返回单个值,如果是TRUE,则全部变为 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  

解决的方法是rep使长度相同

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 并停止。%>%同样,这就是正在发生的事情,但是因为有回收,所以 1 被重复以填满整个组


推荐阅读