过滤,扩展并取两个值之间的差

时间:2019-07-26 13:11:31

标签: r dataframe dplyr

我的目标:计算var列中两个值之间的差。这两个值是与start_dateend_date列中的日期相关联的值。 date列应使用start_dateend_date值进行过滤。

我有如下数据:

# A tibble: 26 x 5
   ID       date                start_date end_date       var
   <chr>    <dttm>              <date>     <date>       <dbl>
 1 23582520 2014-06-30 00:00:00 2014-07-31 2015-06-30  0.103 
 2 23582520 2014-07-31 00:00:00 2014-07-31 2015-06-30 -0.0835
 3 23582520 2014-08-31 00:00:00 2014-07-31 2015-06-30  0.0402
 4 23582520 2014-09-30 00:00:00 2014-07-31 2015-06-30 -0.175 
 5 23582520 2014-10-31 00:00:00 2014-07-31 2015-06-30  0.0673
 6 23582520 2014-11-30 00:00:00 2014-07-31 2015-06-30  0.0386
 7 23582520 2014-12-31 00:00:00 2014-07-31 2015-06-30  0.0255
 8 23582520 2015-01-31 00:00:00 2014-07-31 2015-06-30 -0.0400
 9 23582520 2015-02-28 00:00:00 2014-07-31 2015-06-30  0.0470
10 23582520 2015-03-31 00:00:00 2014-07-31 2015-06-30 -0.0293
# … with 16 more rows

具有2个唯一的ID。

我可以使用以下内容过滤date

x %>%
  filter(date == as.Date(start_date) | date == as.Date(end_date))

哪个给:

# A tibble: 4 x 5
  ID       date                start_date end_date       var
  <chr>    <dttm>              <date>     <date>       <dbl>
1 23582520 2014-07-31 00:00:00 2014-07-31 2015-06-30 -0.0835
2 23582520 2015-06-30 00:00:00 2014-07-31 2015-06-30 -0.0547
3 26550410 2014-07-31 00:00:00 2014-07-31 2015-06-30 -0.0644
4 26550410 2015-06-30 00:00:00 2014-07-31 2015-06-30  0.0357

现在,我想在spread列的基础上date使用数据。因此,它看起来像:

ID         date        var_date_2014_07_31   var_date_2015_06_30
23582520   2014-07-31  -0.0835                   -0.0547
26550410   2014-07-31  -0.0644                    0.0357

然后我可以计算这两列之间的差异。

希望这是一个更清晰的问题。

数据:

data <- structure(list(ID = c("23582520", "23582520", "23582520", "23582520", 
"23582520", "23582520", "23582520", "23582520", "23582520", "23582520", 
"23582520", "23582520", "23582520", "26550410", "26550410", "26550410", 
"26550410", "26550410", "26550410", "26550410", "26550410", "26550410", 
"26550410", "26550410", "26550410", "26550410"), date = structure(c(1404086400, 
1406764800, 1409443200, 1412035200, 1414713600, 1417305600, 1419984000, 
1422662400, 1425081600, 1427760000, 1430352000, 1433030400, 1435622400, 
1404086400, 1406764800, 1409443200, 1412035200, 1414713600, 1417305600, 
1419984000, 1422662400, 1425081600, 1427760000, 1430352000, 1433030400, 
1435622400), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    start_date = structure(c(16282, 16282, 16282, 16282, 16282, 
    16282, 16282, 16282, 16282, 16282, 16282, 16282, 16282, 16282, 
    16282, 16282, 16282, 16282, 16282, 16282, 16282, 16282, 16282, 
    16282, 16282, 16282), class = "Date"), end_date = structure(c(16616, 
    16616, 16616, 16616, 16616, 16616, 16616, 16616, 16616, 16616, 
    16616, 16616, 16616, 16616, 16616, 16616, 16616, 16616, 16616, 
    16616, 16616, 16616, 16616, 16616, 16616, 16616), class = "Date"), 
    var = c(0.102981060743332, -0.0835381224751472, 0.0402144975960255, 
    -0.17477397620678, 0.0672925934195518, 0.0386120080947876, 
    0.0254716500639916, -0.0400183498859406, 0.0469573326408863, 
    -0.0292906425893307, 0.0193761736154556, 0.0120538137853146, 
    -0.0546624027192593, 0.0234585143625736, -0.064396433532238, 
    0.0212319251149893, 0.02939822524786, 0.0147255659103394, 
    0.0681618079543114, -0.117890320718288, 0.10926142334938, 
    -0.0095117473974824, 0.0205932725220919, 0.095668613910675, 
    0.0239877179265022, 0.0357008874416351)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -26L))

编辑:这能解决我的问题吗?

> data %>%
+   filter(date == as.Date(start_date) | date == as.Date(end_date)) %>%
+   spread(key = date, value = var)
# A tibble: 2 x 5
  ID       start_date end_date   `2014-07-31` `2015-06-30`
  <chr>    <date>     <date>            <dbl>        <dbl>
1 23582520 2014-07-31 2015-06-30      -0.0835      -0.0547
2 26550410 2014-07-31 2015-06-30      -0.0644       0.0357

如果我有多个dates而不仅仅是2014-07-312015-06-30,该怎么办呢?

编辑:关于完整数据:

Error: Each row of output must be identified by a unique combination of keys.
Keys are shared for 92 rows:
* 512, 4359
* 3019, 5482
* 3946, 5084
* 1556, 3228
* 822, 5501
* 1985, 5155
* 4634, 4636
* 3706, 5800
* 4778, 4780
* 1478, 1480
* 2152, 2154
* 2871, 3835
* 3012, 3999
* 3366, 5329
* 1736, 5655
* 419, 3317
* 1219, 5466
* 4530, 5578
* 954, 4856
* 3569, 3571
* 513, 4360
* 3020, 5483
* 3947, 5085
* 1557, 3229
* 823, 5502
* 1986, 5156
* 4635, 4637
* 3707, 5801
* 4779, 4781
* 1479, 1481
* 2153, 2155
* 2872, 3836
* 3013, 4000
* 3367, 5330
* 1737, 5656
* 420, 3318
* 1220, 5467
* 4531, 5579
* 955, 4857
* 3570, 3572
* 2110, 3265
* 4101, 4371
* 1574, 3230
* 2111, 3266
* 4102, 4372
* 1575, 3231
Do you need to create unique ID with tibble::rowid_to_column()?
Call `rlang::last_error()` to see a backtrace

编辑2:

运行:

x %>%
  filter(date == as.Date(start_date) | date == as.Date(end_date)) %>%
  mutate(id = row_number()) %>%
  spread(key = date, value = var) %>%
  mutate(diff = `2014-07-31` -`2015-06-30` )

# A tibble: 4 x 7
  ID       start_date end_date      id `2014-07-31` `2015-06-30`  diff
  <chr>    <date>     <date>     <int>        <dbl>        <dbl> <dbl>
1 23582520 2014-07-31 2015-06-30     1      -0.0835      NA         NA
2 23582520 2014-07-31 2015-06-30     2      NA           -0.0547    NA
3 26550410 2014-07-31 2015-06-30     3      -0.0644      NA         NA
4 26550410 2014-07-31 2015-06-30     4      NA            0.0357    NA

2 个答案:

答案 0 :(得分:3)

如果您仅对var的差异感兴趣,则无需传播数据。 您可以过滤然后按ID分组:

data %>%
  filter(date == as.Date(start_date) | date == as.Date(end_date)) %>%
  arrange(date) %>%
  group_by(ID, start_date, end_date) %>%
  summarise(var_diff = var[2] - var[1],
            var_start = var[1],
            var_end = var[2])

# A tibble: 2 x 6
# Groups:   ID, start_date [2]
  ID       start_date end_date   var_diff var_start var_end
  <chr>    <date>     <date>        <dbl>     <dbl>   <dbl>
1 23582520 2014-07-31 2015-06-30   0.0289   -0.0835 -0.0547
2 26550410 2014-07-31 2015-06-30   0.100    -0.0644  0.0357

如果要保留var列,可以使用mutate代替summarise

data %>%
  filter(date == as.Date(start_date) | date == as.Date(end_date)) %>%
  arrange(date) %>%
  group_by(ID) %>%
  mutate(var_diff = var[2] - var[1])

# A tibble: 4 x 6
# Groups:   ID [2]
  ID       date                start_date end_date       var var_diff
  <chr>    <dttm>              <date>     <date>       <dbl>    <dbl>
1 23582520 2014-07-31 00:00:00 2014-07-31 2015-06-30 -0.0835   0.0289
2 26550410 2014-07-31 00:00:00 2014-07-31 2015-06-30 -0.0644   0.100 
3 23582520 2015-06-30 00:00:00 2014-07-31 2015-06-30 -0.0547   0.0289
4 26550410 2015-06-30 00:00:00 2014-07-31 2015-06-30  0.0357   0.100 

答案 1 :(得分:2)

带有data.table

的选项
library(data.table)
setDT(data)[as.Date(date) == as.Date(start_date)|
    date == as.Date(end_date)][order(date), var_diff := last(var) - first(var), ID][]