Объединить кадры данных, округлив даты - PullRequest
1 голос
/ 08 апреля 2020

Я хотел бы объединить два кадра данных в соответствии с их датами, но они могут иметь разные даты. По сути, когда пара групп-дата не идеально совпадает, я хотел бы округлить даты так, чтобы значения во втором фрейме данных соответствовали значениям в первом с максимально возможной датой.

Чтобы быть более понятным Вот пример:

library(dplyr)

data1 <- tibble(
  group = rep(c("A", "B"), each = 3),
  date = c(2002, 2005, 2010, 2001, 2004, 2009),
  variable_1 = c("Thing_1", "Thing_1", "Thing_2", "Thing_1", "Thing_2", "Thing_1")
)

# A tibble: 6 x 3
  group  date variable_1
  <chr> <dbl> <chr>     
1 A      2002 Thing_1   
2 A      2005 Thing_1   
3 A      2010 Thing_2   
4 B      2001 Thing_1   
5 B      2004 Thing_2   
6 B      2009 Thing_1   

data2 <- tibble(
  group = rep(c("A", "B"), each = 2),
  date = c(2007, 2008, 2001, 2010),
  variable_2 = c("Else_1", "Else_2", "Else_2", "Else_1")
)

  group  date variable_2
  <chr> <dbl> <chr>     
1 A      2007 Else_1    
2 A      2008 Else_2    
3 B      2001 Else_2    
4 B      2010 Else_1    

Например, в группе А мы видим, что даты не совпадают: 2002, 2005 и 2010 годы для data1; 2007 и 2008 для data2. Поэтому, поскольку идеальное совпадение невозможно, я бы хотел «округлить» даты. Значение, когда data2$date - 2007, должно совпадать с тем, где data1$date - 2005, поскольку 2005 - самое близкое значение 2007 года. Аналогично, значение, когда data2$date - 2008, должно совпадать с тем, где data1$date это 2010.

То же самое для группы B.

Вот ожидаемый результат:

# A tibble: 6 x 4
  group  date variable_1 variable_2
  <chr> <dbl> <chr>      <chr>     
1 A      2002 Thing_1    NA        
2 A      2005 Thing_1    Else_1    
3 A      2009 Thing_2    Else_2    
4 B      2001 Thing_1    Else_2    
5 B      2004 Thing_2    NA        
6 B      2009 Thing_1    Else_1    

Как я могу это сделать?

Ответы [ 3 ]

1 голос
/ 08 апреля 2020

Использование некоторой арифметики в подходе Map. Поскольку даты имеют числовые значения c, округлить их с шагом пять очень просто. Мы делаем это в обоих фреймах данных и затем используем match.

res <- do.call(rbind, Map(function(x, y) {
  transform(x, variable_2=y$variable_2[
    match(round(x$date / 5)/.2, round(y$date / 5)/.2)
    ])},
  split(data1, data1$group), split(data2, data2$group)))
res
#     group date variable_1 variable_2
# A.1     A 2002    Thing_1       <NA>
# A.2     A 2005    Thing_1     Else_1
# A.3     A 2010    Thing_2     Else_2
# B.4     B 2001    Thing_1     Else_2
# B.5     B 2004    Thing_2       <NA>
# B.6     B 2009    Thing_1     Else_1
0 голосов
/ 08 апреля 2020
data1 <- data.table(data1)
data2 <- data.table(data2)
setkey(data1, "date")
setkey(data2, "date")

data_a <- subset(data1,data1$group=="A")
data_b <- subset(data2,data2$group=="A")

data <- data_a[data_b, roll="TRUE"]
0 голосов
/ 08 апреля 2020

вы можете использовать пакет data.table и проверять наличие подвижных объединений, может помочь roll = "ближайший"

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...