정확한 날짜의 왼쪽 결합 값 및 누락 된 경우 이전 값 찾기

2020-08-01 r dplyr left-join

두 개의 데이터 세트 (df1 및 df2)가 있는데 두 데이터 세트에 left_join하는 데 사용되는 공통 열 "date"및 "country"가 있습니다 (특히 df2의 "price"열). 정확히 일치하는 항목 (날짜 및 국가)이 없으면 누락 된 값 (NA)이 이전 행의 값 (국가 별)으로 채워집니다. 이것은 지금까지 꽤 잘 작동합니다.

그러나 첫 번째 관측치 (국가 별)와 정확히 일치하지 않으면 이전 행으로 채울 수 없기 때문에 문제가 있습니다. 이 경우 NA (예 : 1 행; 2015-07-18)는 2015-07-15에 대한 관측치를 포함하는 df2의 이전 값으로 채워 져야합니다. 2017-07-20이 될 가장 가까운 날짜가 아니라 정확한 날짜 또는 이전 날짜 (최신 알려진 값)에 일치하는 것이 중요합니다.

최종 표에서 2015-07-18 (영국)의 가격은 마지막으로 알려진 값인 2.5 여야합니다.

아래에서 현재 표와 예시 데이터를 찾을 수 있습니다.

   date         country   price
1  2015-07-18   UK        NA  
2  2015-07-20   UK        3.0  
3  2015-07-21   UK        2.7
4  2015-07-22   UK        4.5
5  2015-07-25   UK        4.6
6  2015-07-19   US        1.3
7  2015-07-20   US        2.7
8  2015-07-21   US        3.9
9  2015-07-22   US        2.8
10 2015-07-24   US        2.5
library(dplyr)

date <- c("2015-07-18", "2015-07-20", "2015-07-21", "2015-07-22", "2015-07-25", "2015-07-19", "2015-07-20",
          "2015-07-21", "2015-07-22", "2015-07-24")
country <- c("UK", "UK", "UK", "UK", "UK", "US", "US", "US", "US", "US")

df1 <- cbind.data.frame(date, country)

date <- c("2015-07-15", "2015-07-20", "2015-07-21", "2015-07-22", "2015-07-24", "2015-07-19", "2015-07-20",
          "2015-07-21", "2015-07-22", "2015-07-24")
country <- c("UK", "UK", "UK", "UK", "UK", "US", "US", "US", "US", "US")
price <- c(2.5, 3.0, 2.7, 4.5, 4.6, 1.3, 2.7, 3.9, 2.8, 2.5)

df2 <- cbind.data.frame(date, country, price)

df <- df1 %>%
  left_join(df2, by = c("date", "country"))

df %>%
  group_by(country) %>%
  arrange(date) %>%
  tidyr::fill(price,.direction ="down") %>%
  arrange(country, date) %>%
  ungroup()

Answers

full_join() 시도 할 수 있습니다.

df_b <- df1 %>% 
  full_join(df2, by = c("date", "country")) %>% 
  arrange(country, date) %>% 
  group_by(country) %>% 
  mutate(price = ifelse(is.na(price), lag(price), price)) %>% 
  ungroup() %>% 
  filter(date %in% df$date) %>% 
  inner_join(df, by = c("date", "country")) %>% 
  select(-price.y)
# A tibble: 10 x 3
# date       country price.x
# <chr>      <chr>     <dbl>
#   1 2015-07-18 UK          2.5
# 2 2015-07-20 UK          3  
# 3 2015-07-21 UK          2.7
# 4 2015-07-22 UK          4.5
# 5 2015-07-25 UK          4.6
# 6 2015-07-19 US          1.3
# 7 2015-07-20 US          2.7
# 8 2015-07-21 US          3.9
# 9 2015-07-22 US          2.8
# 10 2015-07-24 US          2.5

Tho Vu가 나를 이겼지 만 여기에 매우 유사한 내 솔루션이 있습니다.

full_join(df1,df2) %>% 
    arrange(country, date) %>% 
    mutate(price=ifelse(is.na(price), lag(price), price))

다음은 data.table 에서 롤링 조인을 사용하는 옵션입니다 (더 짧고 훨씬 빨라야 함).

library(data.table)
setDT(df1)
setDT(df2)
df1[, price := df2[.SD, on=.(country, date), roll=Inf, price]]

산출:

          date country price
 1: 2015-07-18      UK   2.5
 2: 2015-07-20      UK   3.0
 3: 2015-07-21      UK   2.7
 4: 2015-07-22      UK   4.5
 5: 2015-07-25      UK   4.6
 6: 2015-07-19      US   1.3
 7: 2015-07-20      US   2.7
 8: 2015-07-21      US   3.9
 9: 2015-07-22      US   2.8
10: 2015-07-24      US   2.5

데이터:

date <- as.Date(c("2015-07-18", "2015-07-20", "2015-07-21", "2015-07-22", "2015-07-25", "2015-07-19", "2015-07-20",
    "2015-07-21", "2015-07-22", "2015-07-24"))
country <- c("UK", "UK", "UK", "UK", "UK", "US", "US", "US", "US", "US")
df1 <- data.frame(date, country)

date <- as.Date(c("2015-07-15", "2015-07-20", "2015-07-21", "2015-07-22", "2015-07-24", "2015-07-19", "2015-07-20",
    "2015-07-21", "2015-07-22", "2015-07-24"))
country <- c("UK", "UK", "UK", "UK", "UK", "US", "US", "US", "US", "US")
price <- c(2.5, 3.0, 2.7, 4.5, 4.6, 1.3, 2.7, 3.9, 2.8, 2.5)
df2 <- data.frame(date, country, price)

편집 : 여러 열을 찾습니다.

cols <- c("price", "cost", "revenue") 
df1[, (cols) := df2[.SD, on=.(country, date), roll=Inf, mget(cols)]]

Related