R dplyr行式突变

时间:2018-06-21 13:56:24

标签: r dplyr mutate rowwise

大家早上好,这是我第一次在堆栈溢出上发帖。谢谢您的帮助!

我有2个数据框用于分析库存数据。一个数据框除了其他信息外还有日期,我们可以将其称为df:

df1 <- tibble(Key = c('a','b','c'), i =11:13, date= ymd(20110101:20110103))

第二个数据框还包含日期和其他重要信息。

df2 <-tibble(Answer = c('a','d','e','b','f','c'), j =14:19, date= ymd(20150304:20150309))

这是我想做的: 对于df1中的每一行,我需要:

-在df2中查找日期,其中df2 $ answer与df1 $ key相同时,它是最接近该行在df1中的日期。

-然后提取df2中该行中另一列的信息,并将其放在df1中的新行中。

我尝试的代码:

df1 %>%
 group_by(Key, i) %>%
 mutate(
`New Column` =  df2$j[
  which.min(subset(df2$date, df2$Answer== Key) - date)])

结果如下:

Key       i date       `New Column`
1 a        11 2011-01-01           14
2 b        12 2011-01-02           14
3 c        13 2011-01-03           14

这对于第一行a是正确的。在df2中,最接近的日期是2015-03-04,为此,j的值实际上是14

但是,对于第二行Key=b,我希望df2成为子集,以便仅查看df2$Answer = b所在行的日期。因此,日期应为2015-03-07,为此日期为j =17

谢谢您的帮助!

杰西

1 个答案:

答案 0 :(得分:2)

这应该有效:

library(dplyr)
df1 %>% 
  left_join(df2, by = c("Key" = "Answer")) %>% 
  mutate(date_diff = abs(difftime(date.x, date.y, units = "secs"))) %>% 
  group_by(Key) %>% 
  arrange(date_diff) %>% 
  slice(1) %>% 
  ungroup()

我们首先将两个数据帧与left_join连接在一起。是的,我知道每个Key可能有多个约会,请耐心等待。

接下来,我们用mutate计算两个日期absdate.x之间的差的绝对值(date.y)。

现在有了这个,我们将使用Keygroup_by对数据进行分组。这样可以确保每个不同的Key在以后的计算中都将被单独处理。

由于我们已经计算了date_diff,因此我们现在可以对每个arrange的数据进行重新排序(Key),其中最小的date_diff首先Key

最后,我们只对每个date_diff的第一个最小的Key感兴趣,因此我们可以使用slice(1)丢弃其余的内容。

该管道为我们提供了以下内容:

  Key       i date.x         j date.y     date_diff
  <chr> <int> <date>     <int> <date>     <time>   
1 a        11 2011-01-01    14 2015-03-04 131587200
2 b        12 2011-01-02    17 2015-03-07 131760000
3 c        13 2011-01-03    19 2015-03-09 131846400