使用dplyr、定制函数或PURR的多个条件If-Else [英] Multiple condition if-else using dplyr, custom function, or purr

查看:0
本文介绍了使用dplyr、定制函数或PURR的多个条件If-Else的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个结构类似于以下内容的数据框:

set.seed(123)  
df<-data_frame(SectionName = rep(letters[1:2], 50),
               TimeSpentSeconds = sample(0:360, 100, replace = TRUE),
               Correct = sample(0:1, 100, replace = TRUE))

我想通过获取属于特定范围(小于30,介于30-60,介于60-90,...,大于180)的所有TimeSpentSecond值来汇总此数据框,将时间标记为这些范围,按sectionName对它们进行分组,并找到正确列的总和,以使结果数据框看起来如下所示:

    TimeGroup             SectionName Correct
   <fct>                 <chr>         <int>
 1 LessThan30Secs        a                 2
 2 LessThan30Secs        b                 3
 3 30-60 Seconds         a                 4
 4 30-60 Seconds         b                 3
 5 60-90 Seconds         a                 2
 6 60-90 Seconds         b                 3
 7 90-120 Seconds        a                 4
 8 90-120 Seconds        b                 0
 9 120-150 Seconds       a                 4
10 120-150 Seconds       b                 0
11 150-180 Seconds       a                 1
12 150-180 Seconds       b                 2
13 GreaterThan180Seconds a                11
14 GreaterThan180Seconds b                11

我使用下面的if-Else代码成功地做到了这一点,在该代码中,我将所有时间都突变为具有适当标签、分组和汇总的新列:

x <- c("LessThan30Secs", "30-60 Seconds", "60-90 Seconds","90-120 Seconds", 
           "120-150 Seconds", "150-180 Seconds", "GreaterThan180Seconds") 

df %>% 
mutate(TimeGroup = if_else(TimeSpentSeconds >= 0 & TimeSpentSeconds <= 30, "LessThan30Secs",
                if_else(TimeSpentSeconds > 30 & TimeSpentSeconds <= 60, "30-60 Seconds",
                if_else(TimeSpentSeconds > 60 & TimeSpentSeconds <= 90, "60-90 Seconds",
                if_else(TimeSpentSeconds > 90 & TimeSpentSeconds <= 120, "90-120 Seconds",
                if_else(TimeSpentSeconds > 120 & TimeSpentSeconds <= 150, "120-150 Seconds", 
                if_else(TimeSpentSeconds > 150 & TimeSpentSeconds <= 180, "150-180 Seconds",
                if_else(TimeSpentSeconds > 180, "GreaterThan180Seconds", "")))))))) %>%
    mutate(TimeGroup = factor(TimeGroup, levels = x)) %>%
    arrange(TimeGroup) %>%
    group_by(TimeGroup, SectionName) %>%
    summarise(Correct = sum(Correct))

但是,必须有更好的方法来做到这一点。我考虑过写函数,但没有走得很远,因为我不擅长写函数。

有没有人想出一种更好的方式,通过一种我没有想到的dplyr方法来实现同样的输出,编写一个定制函数,也许在某个时候使用Purrr包,或者其他一些r函数?

推荐答案

case_when()将执行您想要的操作。它是嵌套ifelse()语句的整齐替代方案。

library(dplyr)

mutate(df,
       TimeGroup = case_when(
         TimeSpentSeconds <= 30 ~ "30 Seconds or less",
         TimeSpentSeconds <= 60 ~ "31-60 Seconds",
         TimeSpentSeconds <= 90 ~ "61-90 Seconds",
         TimeSpentSeconds <= 120 ~ "91-120 Seconds",
         TimeSpentSeconds <= 150 ~ "121-150 Seconds", 
         TimeSpentSeconds <= 180 ~ "151-180 Seconds",
         TimeSpentSeconds > 180 ~ "Greater Than 180 Seconds",
         TRUE ~ NA_character_)
)

最后一个参数是不符合任何条件的记录的全部捕获,例如如果时间以某种方式小于0秒。

这篇关于使用dplyr、定制函数或PURR的多个条件If-Else的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆