首页 > 解决方案 > 使用 dplyr 计算 R 数据帧中的成对差异

问题描述

我创建了一个简单的数据框:

library(dplyr)

df <- tibble(
        UserId = c("A", "A", "A", "A", "A", "B", "B", "B", "B"),
        Answer_Date = as.Date(c("2010-12-31", "2011-12-29", "2012-12-25", "2013-12-10", "2014-12-31", "2010-10-31", "2011-10-28", "2013-10-31", "2015-10-31")),
        Q1 = c(3, 1, 1, 0, 1, 4, 2, 5, 4),
        Q2 = c(2, 0, 1, 2, 1, 8, 2, 6, 5),
      ) %>%
        group_by(UserId) %>%
        mutate(First_Date = min(Answer_Date)) %>%
        mutate(Last_Date  = max(Answer_Date)) %>%
        ungroup()

这给了我

> df
# A tibble: 9 x 6
  UserId Answer_Date    Q1    Q2 First_Date Last_Date 
  <chr>  <date>      <dbl> <dbl> <date>     <date>    
1 A      2010-12-31      3     2 2010-12-31 2014-12-31
2 A      2011-12-29      1     0 2010-12-31 2014-12-31
3 A      2012-12-25      1     1 2010-12-31 2014-12-31
4 A      2013-12-10      0     2 2010-12-31 2014-12-31
5 A      2014-12-31      1     1 2010-12-31 2014-12-31
6 B      2010-10-31      4     8 2010-10-31 2015-10-31
7 B      2011-10-28      2     2 2010-10-31 2015-10-31
8 B      2013-10-31      5     6 2010-10-31 2015-10-31
9 B      2015-10-31      4     5 2010-10-31 2015-10-31

我现在希望计算每个主题在他们回答问卷的第一个日期和最后一个日期之间答案的变化。我从写作开始

df_tmp <- df %>%
            filter(Answer_Date == First_Date) %>%
            select(c("UserId", "Q1", "Q2"))
colnames(df_tmp) <- c("UserId", paste0("First_Response_", c("Q1", "Q2")))
df <- merge(df, df_tmp, by = "UserId") 

df_tmp <- df %>%
            filter(Answer_Date == Last_Date) %>%
            select(c("UserId", "Q1", "Q2"))
colnames(df_tmp) <- c("UserId", paste0("Last_Response_", c("Q1", "Q2")))
df <- merge(df, df_tmp, by = "UserId")

给我

> df
  UserId Answer_Date Q1 Q2 First_Date  Last_Date First_Q1 First_Q2 Last_Q1 Last_Q2
1      A  2010-12-31  3  2 2010-12-31 2014-12-31        3        2       1       1
2      A  2011-12-29  1  0 2010-12-31 2014-12-31        3        2       1       1
3      A  2012-12-25  1  1 2010-12-31 2014-12-31        3        2       1       1
4      A  2013-12-10  0  2 2010-12-31 2014-12-31        3        2       1       1
5      A  2014-12-31  1  1 2010-12-31 2014-12-31        3        2       1       1
6      B  2010-10-31  4  8 2010-10-31 2015-10-31        4        8       4       5
7      B  2011-10-28  2  2 2010-10-31 2015-10-31        4        8       4       5
8      B  2013-10-31  5  6 2010-10-31 2015-10-31        4        8       4       5
9      B  2015-10-31  4  5 2010-10-31 2015-10-31        4        8       4       5

我现在希望创建两个 now 列,Delta_Q1 = Last_Q1 - First_Q1and Delta_Q2 = Last_Q2 - First_Q2,但(可能)使用mutate, paste0("First_", c("Q1", "Q2")), paste0("Last_", c("Q1", "Q2"))and paste0("Delta_", c("Q1", "Q2"))

顺序计算列对之间的差异(或通常是两个变量的某些函数)的正确语法是什么?我不想手动写下差异的原因很简单——真正的数据框有很多对列。

非常感谢您的帮助。

真挚地

托马斯飞利浦

标签: rdplyr

解决方案


您可以创建两个列向量并直接将它们相减以创建新列。

first_r_col <- grep('First_Response', colnames(df))
last_r_col <- grep('Last_Response', colnames(df))
df[paste0('delta', seq_along(first_r_col))] <- df[last_r_col] - df[first_r_col]

使用dplyr select语句可能是选择列的简单方法。

library(dplyr)
df[paste0('delta', seq_along(first_r_col))]  <- 
         df %>% select(starts_with('Last_Response')) - 
         df %>% select(starts_with('First_Response'))

推荐阅读