使用dplyr汇总条件

时间:2019-02-22 10:15:10

标签: r dplyr summarize

我目前正在尝试应用摘要功能,以便从大型数据集中隔离相关的观察结果。此处提供了一个简单的可重现示例:

df <- data.frame(c(1,1,1,2,2,2,3,3,3), as.logical(c(TRUE,FALSE,TRUE,TRUE,TRUE,TRUE,FALSE,TRUE,FALSE)),
                 as.numeric(c(0,5,0,0,0,0,7,0,7)))
colnames(df) <- c("ID", "Status", "Price")

  ID Status Price
1  1   TRUE     0
2  1  FALSE     5
3  1   TRUE     0
4  2   TRUE     0
5  2   TRUE     0
6  2   TRUE     0
7  3  FALSE     7
8  3   TRUE     0
9  3  FALSE     7

我只想按观察值对表进行排序,并且仅当所有三个观察值都为真(变通)时才将状态为TRUE,然后要获取与该状态相对应的价格(即,对于观察值1为FALSE,对于观察值1为0,观察2为TRUE,观察7为FALSE)。

根据Summarize with conditions in dplyr,我发现我可以像平常一样在方括号中指定条件。到目前为止,我的代码如下:

library(dplyr)
result <- df %>%
  group_by(ID) %>%
  summarize(Status = all(Status), Test = ifelse(all(Status) == TRUE,
 first(Price[Status == TRUE]), first(Price[Status == FALSE]))) 

# This is what I get: 
# A tibble: 3 x 3
     ID Status  Test
  <dbl> <lgl>  <dbl>
1    1. FALSE     0.
2    2. TRUE      0.
3    3. FALSE     7.

但是您可以看到,对于ID = 1,它给出了不正确的价格。我一直在尝试这种方法,因此,如果我在哪里出错,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

可以做到:

df %>%
  group_by(ID) %>%
  mutate(status = Status) %>%
  summarise(
    Status = all(Status),
    Test = ifelse(Status == TRUE,
                  first(Price),
                  first(Price[status == FALSE]))
  )

输出:

# A tibble: 3 x 3
     ID Status  Test
  <dbl> <lgl>  <dbl>
1     1 FALSE      5
2     2 TRUE       0
3     3 FALSE      7

问题是您想在修改Status列时使用Test,以使其不再包含原始值。

之前制作副本(我已经将其保存在status中),对其执行ifelse,它将运行良好。

答案 1 :(得分:1)

我们可以将all(Status)保留为summarise中的第二个参数(或更改列名),并且也可以使用if/else完成,因为逻辑似乎返回单个TRUE / FALSE,取决于“状态”的all是否为真

df %>%
   group_by(ID) %>% 
   summarise( Test = if(all(Status)) first(Price[Status]) else 
                   first(Price[!Status]), Status = all(Status))
# A tibble: 3 x 3
#     ID  Test Status
#   <dbl> <dbl> <lgl> 
#1     1     5 FALSE 
#2     2     0 TRUE  
#3     3     7 FALSE 

注意:最好不要使用长度不相等的ifelse作为参数