Как мне объединить кадры данных неравной длины на основе условия - PullRequest
3 голосов
/ 17 октября 2019

Я хотел бы знать, как наилучшим образом объединить два следующих фрейма данных:

df1 <- data.frame(Date = c(1,2,3,4,5,6,7,8,9,10),
                  Altitude=c(100,101,101,102,103,99,98,99,89,70))

> df1
   Date Altitude
1     1      100
2     2      101
3     3      101
4     4      102
5     5      103
6     6       99
7     7       98
8     8       99
9     9       89
10   10       70

df2 <- data.frame(Start = c(1,4,8),Stop = c(3,7,10),Longitude=c(10,12,13))

> df2
  Start Stop Longitude
1     1    3        10
2     4    7        12
3     8   10        13

В основном мне понадобится третий столбец в df2, с долготой, основанной на том, находится ли Date между Start и Stop,в результате получилось что-то вроде этого:

   Date Altitude Longitude
1     1      100        10
2     2      101        10
3     3      101        10
4     4      102        12
5     5      103        12
6     6       99        12
7     7       98        12
8     8       99        13
9     9       89        13
10   10       70        13

Я пробовал все виды поднабора, фильтрации, ... но я просто не могу понять это. Любая помощь будет оценена!

С уважением

Ответы [ 3 ]

2 голосов
/ 17 октября 2019

Идея с помощью dplyr состоит в том, чтобы завершить запуск: последовательность останова, развертывание и объединение, т.е.

library(dplyr)

df2 %>% 
 mutate(Date = mapply(seq, Start, Stop)) %>% 
 tidyr::unnest() %>% 
 select(-c(1, 2)) %>% 
 right_join(df1, by = 'Date')

, что дает,

   Longitude Date Altitude
1         10    1      100
2         10    2      101
3         10    3      101
4         12    4      102
5         12    5      103
6         12    6       99
7         12    7       98
8         13    8       99
9         13    9       89
10        13   10       70
1 голос
/ 17 октября 2019

Здесь приведен двусторонний ответ с использованием функций group_by и group_modify в пакете dplyr (представлен в версии 0.8.1 в мае 2019 года).

library(dplyr)    
df1 %>% 
      group_by(Date, Altitude) %>%
      group_modify(~ data.frame(df2 %>% 
                                  filter(.x$Date >= Start, .x$Date <= Stop)) %>% 
                                  select(Longitude), 
                   keep = TRUE)

Для каждой уникальной комбинации вdf1 даты и высоты (т. Е. Для каждой строки), это находит долготу, соответствующую диапазону дат в df2.

Выходные данные - тиббл:

# A tibble: 10 x 3
# Groups:   Date, Altitude [10]
    Date Altitude Longitude
   <dbl>    <dbl>     <dbl>
 1     1      100        10
 2     2      101        10
 3     3      101        10
 4     4      102        12
 5     5      103        12
 6     6       99        12
 7     7       98        12
 8     8       99        13
 9     9       89        13
10    10       70        13
0 голосов
/ 17 октября 2019

Решение Base R:

ind <- apply(df2, 1, function(x) which(df1$Date >= x[1] & df1$Date <= x[2]))
df1$Longitude <- unlist(Map(function(x,y) rep(y, length(x)), ind, df2$Longitude))

Выход

Date Altitude Longitude
1     1      100        10
2     2      101        10
3     3      101        10
4     4      102        12
5     5      103        12
6     6       99        12
7     7       98        12
8     8       99        13
9     9       89        13
10   10       70        13
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...