【问题标题】:Finding difference between specific rows by group按组查找特定行之间的差异
【发布时间】:2018-02-10 02:35:15
【问题描述】:

在一个组中,我想找出该行与该用户第一次出现在数据中的差异。例如,我需要在下面创建diff 变量。用户的行数各不相同,如下数据所示:

df <- structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 4L), 
    money = c(9L, 12L, 13L, 15L, 5L, 7L, 8L, 5L, 2L, 10L), occurence = c(1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 1L, 1L, 2L), diff = c(NA, 3L, 4L, 
    6L, NA, 2L, 3L, NA, NA, 8L)), .Names = c("ID", "money", "occurence", 
"diff"), class = "data.frame", row.names = c(NA, -10L))

   ID money occurence diff
1   1     9         1   NA
2   1    12         2    3
3   1    13         3    4
4   1    15         4    6
5   2     5         1   NA
6   2     7         2    2
7   2     8         3    3
8   3     5         1   NA
9   4     2         1   NA
10  4    10         2    8

【问题讨论】:

    标签: r dataframe rows


    【解决方案1】:

    您可以使用ave()。我们只需删除每个组的第一个值并将其替换为NA,然后从其余值中减去第一个值。

    with(df, ave(money, ID, FUN = function(x) c(NA, x[-1] - x[1])))
    # [1] NA  3  4  6 NA  2  3 NA NA  8
    

    【讨论】:

      【解决方案2】:

      一个解决方案,它使用first函数获取第一个值并计算差值。

      library(dplyr)
      
      df2 <- df %>%
        group_by(ID) %>%
        mutate(diff = money - first(money)) %>%
        mutate(diff = replace(diff, diff == 0, NA)) %>%
        ungroup()
      df2
      # # A tibble: 10 x 4
      #       ID money occurence  diff
      #    <int> <int>     <int> <int>
      #  1     1     9         1    NA
      #  2     1    12         2     3
      #  3     1    13         3     4
      #  4     1    15         4     6
      #  5     2     5         1    NA
      #  6     2     7         2     2
      #  7     2     8         3     3
      #  8     3     5         1    NA
      #  9     4     2         1    NA
      # 10     4    10         2     8
      

      更新

      这是 Sotos 提供的 解决方案。请注意,无需将 0 替换为 NA

      library(data.table)
      
      setDT(df)[, money := money - first(money), by = ID][]
      #     ID money occurence diff
      #  1:  1     0         1   NA
      #  2:  1     3         2    3
      #  3:  1     4         3    4
      #  4:  1     6         4    6
      #  5:  2     0         1   NA
      #  6:  2     2         2    2
      #  7:  2     3         3    3
      #  8:  3     0         1   NA
      #  9:  4     0         1   NA
      # 10:  4     8         2    8
      

      数据

      dput(df)
      structure(list(ID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 4L), 
          money = c(9L, 12L, 13L, 15L, 5L, 7L, 8L, 5L, 2L, 10L), occurence = c(1L, 
          2L, 3L, 4L, 1L, 2L, 3L, 1L, 1L, 2L)), .Names = c("ID", "money", 
      "occurence"), row.names = c(NA, -10L), class = "data.frame")
      

      【讨论】:

      • 这也有效:df %&gt;% group_by(ID) %&gt;% mutate(diff2 = money - money[1]) 但我犹豫是否将其发布为真正的答案......我不确定这在某些情况下是否会失败。我注意到它有效,但没有看到很多这种语法的例子。
      • 仅供参考,您不需要两个变异。 ... %&gt;% mutate(diff = money - first(money), diff = replace(diff, diff == 0, NA)) 工作得很好。同样data.table 有一个函数first,它的默认值为NA,即setDT(df)[, money := money - first(money), by = ID]。如果你愿意,你也可以在你的答案中添加这个。
      • @MattL。谢谢你的评论。我认为您的解决方案有效。
      • @Sotos 感谢您的评论。我将更新我的帖子,包括您的建议和data.table 解决方案。
      猜你喜欢
      • 2021-06-24
      • 2018-10-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-12
      • 2023-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多