R-dplyr行突变
大家早上好,这是我第一次发布关于堆栈溢出的帖子。谢谢你的帮助 我有两个数据框,我用它来分析股票数据。一个数据框包含日期和其他信息,我们可以称之为df:R-dplyr行突变,r,dplyr,mutate,rowwise,R,Dplyr,Mutate,Rowwise,大家早上好,这是我第一次发布关于堆栈溢出的帖子。谢谢你的帮助 我有两个数据框,我用它来分析股票数据。一个数据框包含日期和其他信息,我们可以称之为df: df1 <- tibble(Key = c('a','b','c'), i =11:13, date= ymd(20110101:20110103)) 其结果是: Key i date `New Column` 1 a 11 2011-01-01 14 2 b 12
df1 <- tibble(Key = c('a','b','c'), i =11:13, date= ymd(20110101:20110103))
其结果是:
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
谢谢你的帮助
Jesse这应该可以:
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\u join
连接两个数据帧。是的,我知道每个键可能有多个日期,请放心
接下来,我们计算(使用mutate
)两个日期date.x
和date.y
之间差值的绝对值(abs
)
现在我们有了这个,我们将使用groupby
按键对数据进行分组。这将确保在后续计算中分别处理每个不同的键
由于我们已经计算了日期_diff
,现在可以对每个键
的数据重新排序(排列
),每个键
的第一个数据是最小的日期_diff
最后,对于每个键
,我们只对第一个最小的日期差异感兴趣,因此我们可以使用切片(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
Key i date.x j date.y date\u diff
1A 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
重命名日期列,这样它们就不会共享名称,左键连接上的数据“Answer”=“Key”
,根据日期列中的差异排列,按答案分组,从每个组的顶行(最小的日期差异,因为排序)。感谢您的帮助Gregor!你是说让df2在左边,df1在右边,像left_join(df2,df1,by=c(“应答”=“键”)
?如果我用另一种方式做的话,它是不被接受的,因为Key
只有3个值,Answer
有6个df1%>%right\u join(df2,by=c('Key'='Answer'))%%>%group\u by(Key)%%>%arrange(abs(date.x-date.y))%%>%slice(1)
我相信是格雷戈的建议(或切换df2
和df1
并将右连接
更改为左连接
)嗨,Ryan和Gregor。这个建议的问题虽然有帮助,但在实际数据中,日期并不完全匹配。如果我尝试通过Key=Answer
加入,每个键都有许多匹配的答案,如果通过c(“Key”=“Answer”,“date=”date)加入,日期不完全匹配,这就是为什么我需要使用which.min来查找最接近的日期来将它们链接起来,而不是相同的日期。在加入后,您将忽略我的注释中的所有内容。您通过Key=Answer加入,这会导致许多匹配。我的注释的其余部分告诉您如何查找最接近的日期并删除所有其他行:排列、分组、切片。这与您的which.min
做的事情相同,但工作流程更简单。因为这些是日期,而不是日期时间,所以您可以简化为date\u diff=abs(date.x-date.y)
以天为单位计算差异。在OP的例子中,我绝对同意你的观点。但是,对于其他遇到类似问题的人,我试图保持我的回答的灵活性。嗨,谢谢你的帮助。我的问题是,在实际的数据集中,每个键都有多行,所以当我尝试执行left_join,我得到错误错误:无法分配大小为23.1 Mb的向量。我只需使用内存向R添加更多内存。限制
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()
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