【问题标题】:How to calculate difference of measures between groups considering the date如何计算考虑日期的组间测量值的差异
【发布时间】:2021-12-02 02:15:02
【问题描述】:

我正在苦苦思索如何计算按日期、按组排列的第一个值和最后一个值之间的差异。这是一个玩具示例:

  test1 = data.frame(my_groups = c("A", "A", "A", "B", "B", "B", "C", "C", "C",  "A", "A", "A"),
                     measure = c(10, 20, 5, 64, 2, 62 ,2, 5, 4, 6, 7, 105),
                     #distance = c(),
                     time= as.Date(c("20-09-2020", "25-09-2020", "19-09-2020", "20-05-2020", "20-05-2020", "20-06-2021", 
                             "11-01-2021", "13-01-2021", "13-01-2021", "15-01-2021", "15-01-2021", "19-01-2021"), format = "%d-%m-%Y"))
  
  # test1 %>% arrange(my_groups, time)
  #    my_groups measure       time
  # 1          A       5 2020-09-19
  # 2          A      10 2020-09-20
  # 3          A      20 2020-09-25
  # 4          A       6 2021-01-15
  # 5          A       7 2021-01-15
  # 6          A     105 2021-01-19
  # 7          B      64 2020-05-20
  # 8          B       2 2020-05-20
  # 9          B      62 2021-06-20
  # 10         C       2 2021-01-11
  # 11         C       5 2021-01-13
  # 12         C       1 2021-01-13

#desired result
  #    my_groups    diff            
  # 1          A     100 (105 - 5)
  # 2          B       2 (64 - 62)
  # 3          C       1 (1 - 2)

desired result 中括号内的等式只是为了说明diff 的来源。

任何提示我该怎么做?

【问题讨论】:

  • A 不应该是 105-5 = 100 吗?
  • 和 C 1 - 2 = -1 ?
  • 另外.. 你会如何处理 C 中的领带?
  • 对于领带,我将采取最小措施。为此,我想到了先安排数据框

标签: r dplyr


【解决方案1】:

data.frame 中的示例数据与您的控制台输出不匹配,因此结果会有所不同。

两种方法,取决于几个因素。

  1. 假设订单是外部控制的,

    test1 %>%
      group_by(my_groups) %>%
      slice(c(1, n())) %>%
      summarize(diff = diff(measure))
    # # A tibble: 3 x 2
    #   my_groups  diff
    #   <chr>     <dbl>
    # 1 A            95
    # 2 B            -2
    # 3 C             2
    

    或者只是

    test1 %>%
      group_by(my_groups) %>%
      summarize(diff = measure[n()] - measure[1])
    

    这样做的好处是它可以解决下面方法 2 的问题(与which.max 相关):如果您自己控制排序,则可以保证使用您需要的第一个/最后一个值。

    注意,对于这部分,我假设您在示例数据中提供给我们的数据顺序是相关的。我假设有某种方法可以保证找到您的结果。有了您的最新评论,我们可以在总结前arrange,并与您更接近您想要的结果

    test1 %>%
      arrange(time, -measure) %>%      # this is the "external" sorting I mentioned, so we don't need which.min/.max
      group_by(my_groups) %>%
      summarize(diff = measure[n()] - measure[1])
    # # A tibble: 3 x 2
    #   my_groups  diff
    #   <chr>     <dbl>
    # 1 A           100
    # 2 B            -2
    # 3 C             2
    
  2. 没有预排序,我们可以使用which.minwhich.max。这样做的问题是,当出现平局时,它可能不会选择您想要的那个。

    test1 %>%
      group_by(my_groups) %>%
      summarize(diff = measure[which.max(time)] - measure[which.min(time)])
    # # A tibble: 3 x 2
    #   my_groups  diff
    #   <chr>     <dbl>
    # 1 A           100
    # 2 B            -2
    # 3 C             3
    

【讨论】:

  • OP 应该阐明如何处理平局。您的解决方案为 C 返回两个不同的输出。[但是,我不明白为什么 A 有两个不同的值]
  • 为清晰起见进行了编辑。此外,OP 应该澄清为什么他们的预期结果与他们的样本数据不一致(这与他们的样本数据的控制台输出不一致)。
  • 为我工作!谢谢你,@r2evans!
  • @Edo,为了记录,我不喜欢这里的不同方法都会产生不同结果的事实。我们无法控制数据,我们只能根据假设进行工作,并希望能清楚地捕捉到它们。感谢您的来信。
【解决方案2】:
test1 %>%
    dplyr::group_by(my_groups) %>%
    dplyr::mutate(
        first = min(time), last = max(time),
    ) %>% 
    dplyr::select(-time, -measure) %>%
    dplyr::distinct() %>%
    dplyr::mutate(diff = first - last) %>%
    dplyr::select(-first, -last)

【讨论】:

  • 这种方法返回了日期的差异
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
相关资源
最近更新 更多