2017-08-17 18 views
3

我有兩個數據幀(df1df2)。我正在使用dplyr來操縱我的數據。不過,我有一些困難就找到了以下結果:試圖合併具有特定條件和行中間隙的兩個數據幀R

df1包含一些有關idpricedateid不是唯一的:一個給定的id可以決定的幾個價格)

df2可以告訴如果一個給定的ID有價格和/或日期價值的修改df1

我想知道是否有價格和/或日期的修改,如果是這樣的話,我想採取這個新價值作爲價格/日期

但是,df1df2可能有點棘手,因爲您可以對給定的id有多個修改。

更具體地說,價格給定的修改(如果存在的話,否則我參加df1給出的價格),我想將它與日期(如果存在的最後修改關聯,否則我把給定的日期在DF1),只要它是<= df1$date + 30

概括起來,這裏有一個例子:

df1 <- data.frame(
     Id = c(1,1,2), 
     price = c(1000,2000,1000), 
     date = c("2016-01-01","2016-09-01","2016-01-01") 
    ) 
df1 
    Id price  date 
    1 1000 2016-01-01 
    1 2000 2016-09-01 
    2 1000 2016-01-01 

而且DF2如下:

df2 <- data.frame(
    Id = c(1,1,1,1,1,2,2), 
    price = c(1500,NA,2000,NA,3000,NA,NA), 
    date = c(NA, "2016-01-03", "2016-01-05", "2016-09-02","2016-09-03","2016-01-03","2016-01-05") 
) 

df2 
    Id price  date 
    1 1500  <NA> 
    1 NA 2016-01-03 
    1 2000 2016-01-05 
    1 NA 2016-09-02 
    1 3000 2016-09-03 
    2 NA 2016-01-03 
    2 NA 2016-01-05 

我希望的結果有一些與此類似:

Id initial_price initial_date is_modification_price is_modification_date true_price true_date 

    1 1000   2016-01-01   TRUE      TRUE    2000  2016-01-05 
    1 2000   2016-09-01   TRUE      TRUE    3000  2016-09-03 
    2 1000   2016-01-01   FALSE     TRUE    1000  2016-01-05 

我希望我足夠清楚

有誰有如何實現這一點的想法;或甚至完全不同的方法?

回答

1

首先,準備dataframes:

# fix type 
df1 <- mutate(df1, date = as.Date(date)) 

# fill NAs in df2 
df2 <- df2 %>% 
    mutate(date = as.Date(date)) %>% 
    group_by(Id) %>% 
    tidyr::fill(price, date) %>% 
    ungroup 

# fill remaining NAs with default values taken from df1 
default_values <- df1 %>% 
    group_by(Id) %>% 
    slice(1) %>% 
    rename(price0 = price, date0 = date) %>% 
    ungroup 

df2 <- df2 %>% 
    left_join(default_values, by = "Id") %>% 
    mutate(price = if_else(is.na(price), price0, price), 
     date = if_else(is.na(date), date0, date)) %>% 
    select(Id, price, date) 

然後加入:

df1 %>% 
    left_join(df2, by = "Id") %>% 
    filter(date.y <= date.x + 30) %>% 
    group_by(Id, price.x, date.x) %>% 
    arrange(date.y) %>% 
    slice(n()) %>% 
    ungroup %>% 
    rename(initial_price = price.x, initial_date = date.x, 
     true_price = price.y, true_date = date.y) %>% 
    mutate(is_modification_price = (initial_price != true_price), 
     is_modification_date = (initial_date != true_date)) 
# # A tibble: 3 x 7 
#  Id initial_price initial_date true_price true_date is_modification_price is_modification_date 
# <dbl>   <dbl>  <date>  <dbl>  <date>     <lgl>    <lgl> 
# 1  1   1000 2016-01-01  2000 2016-01-05     TRUE     TRUE 
# 2  1   2000 2016-09-01  3000 2016-09-03     TRUE     TRUE 
# 3  2   1000 2016-01-01  1000 2016-01-05     FALSE     TRUE 

注意,left_join隨後filter在最後一步可能需要太多內存。如果是這種情況,請使用data.table中的非等聯接功能。