在dplyr中的group_by内有条件地忽略值

时间:2018-06-07 10:27:48

标签: r dplyr grouping

请考虑以下事项。

背景

data.frame我有患者ID(id),患者入院的日期(day),他们当天收到的诊断活动代码(code),该活动的价格(price)以及该活动的频率(freq)。

code bc的活动同时注册,但意味着或多或少相同,不应重复计算。

问题

我想要的是:如果code" b"和" c"已注册当天code" b"应该被忽略。

示例data.frame如下所示:

x <- data.frame(id = c(rep("a", 4), rep("b", 3)),
            day = c(1, 1, 1, 2, 1, 2, 3),
            price = c(500, 10, 100, rep(10, 3), 100),
            code = c("a", "b", "c", rep("b", 3), "c"),
            freq = c(rep(1, 5), rep(2, 2))))

> x
  id day price code freq
1  a   1   500    a    1
2  a   1    10    b    1
3  a   1   100    c    1
4  a   2    10    b    1
5  b   1    10    b    1
6  b   2    10    b    2
7  b   3   100    c    2

因此患者的成本&#34; a&#34;对于第1天将是600而不是610,因为我可以使用以下计算:

x %>% 
  group_by(id, day) %>% 
  summarise(res = sum(price * freq))

# A tibble: 5 x 3
# Groups:   id [?]
  id      day   res
  <fct> <dbl> <dbl>
1 a        1.  610.
2 a        2.   10.
3 b        1.   10.
4 b        2.   20.
5 b        3.  200.

可能的方法

要么删除观察code&#34; b&#34;什么时候&#34; c&#34;在同一天出现,或者我设置了freq&#34; b&#34; code如果code&#34; c&#34;在同一天出现。

到目前为止,ifelsemutate的所有尝试都失败了。

非常感谢每一位帮助。非常感谢你提前!

2 个答案:

答案 0 :(得分:2)

您可以添加filter行来删除违规b这样的值......

x %>% 
  group_by(id, day) %>% 
  filter(!(code=="b" & "c" %in% code)) %>% 
  summarise(res = sum(price * freq))

  id      day   res
  <fct> <dbl> <dbl>
1 a        1.  600.
2 a        2.   10.
3 b        1.   10.
4 b        2.   20.
5 b        3.  200.

答案 1 :(得分:0)

您可以像这样创建一个新列:

mutate(code_day = paste0(ifelse(code %in% c("b", "c"), "z", code), day)

然后你的所有B和C将成为Zs(不会丢失原始代码列,可以帮助你区分它们)。然后,您可以按代码降序排列,并删除co​​de_day列中的重复值:

arrange(desc(code)) %>% # Bs will come after Cs
distinct(code_day, .keep_all = TRUE)