2016-06-01 4 views
1

Скажем, у меня есть кадр данных ниже. (Набор данных, которые у меня есть, не обязательно так мал, как это.)Корреляции дня от времени путем сопоставления имени

library(lubridate) 

x <- data.frame(
    date = c(rep(ymd(20160601), 4), rep(ymd(20160602), 3), rep(ymd(20160603), 3)), 
    name = c("a", "b", "c", "d", "a", "b", "c", "b", "c", "d"), 
    observation = sample(1:10) 
) 

#   date name observation 
# 1 2016-06-01 a   10 
# 2 2016-06-01 b   7 
# 3 2016-06-01 c   3 
# 4 2016-06-01 d   2 
# 5 2016-06-02 a   8 
# 6 2016-06-02 b   6 
# 7 2016-06-02 c   4 
# 8 2016-06-03 b   5 
# 9 2016-06-03 c   1 
# 10 2016-06-03 d   9 

Я хочу найти повседневно корреляцию наблюдений соответствующих имен, то есть на дату 2016-06-02, я хочу найти корреляцию между < 8, 6, 4> и < 10, 7, 3>, потому что только a, b и c являются общими как в 2016-06-02, так и в 2016-06-01. Я могу это сделать как таковой (есть, вероятно, лучший способ сделать это):

filter(x, date %in% ymd(20160601)) %>% 
    left_join(filter(x, date %in% ymd(20160602)), by = "name") %>% 
    transmute(
    date = ymd(20160602), 
    correlation = cor(observation.x, observation.y, use = "complete.obs")) %>% 
    `[`(1,) 

#   date correlation 
# 1 2016-06-02 0.9966159 

Но как я это делаю для всего кадра данных с использованием оконных функций, так что я получаю кадр данных, который состоит из всех даты и их корреляции с предыдущей датой? Я бы предпочел решение dplyr/RcppRoll!

ответ

3

dplyr не имеет прокатных слияний. Предполагая, что вам действительно нужен один (не видно из OP, поскольку в образце данных нет отверстий), вы можете сделать:

library(data.table) 
dt = as.data.table(x) # or setDT to convert in place 

dt[, date := as.Date(date)] # not very clear from OP if you have dates or datetimes 
          # let's make sure it's dates 

dt[.(name = name, old.date = date - 1, obs = observation), 
    on = c(name = 'name', date = 'old.date'), roll = T][ 
    , cor(obs, observation, use = 'pairwise.complete.obs'), by = date] 
#   date   V1 
#1: 2016-06-01   NA 
#2: 2016-06-02 0.9966159 
#3: 2016-06-03 -0.5000000 
+0

Еще один вопрос; как бы мы это сделали, не сворачивая слияния, если это проще? –

+0

@ZaferCesur, если ваши данные не имеют отверстий, вы можете просто «сдвинуть» свои наблюдения – eddi

Смежные вопросы