如何使用 R 中分组列的 'nearest time' 加入 tibbles/dataframes?
How to join tibbles/dataframes by using the 'nearest time' of a grouping column in R?
我在下面举例说明了这个数据集:
library(lubridate)
library(tidyverse)
id <- c("A", "A", "B", "B")
date <- ymd(c("2017-11-26", "2017-11-26", "2017-11-26", "2017-11-29"))
time <- hms(c("09:25:30", "10:10:02", "09:15:36", "9:50:55"))
variable1 <- c("67", "30", "28", "90")
df <- tibble(id, date, time, variable1)
df
A tibble: 4 x 4
id date time variable1
<chr> <date> <Period> <chr>
1 A 2017-11-26 9H 25M 30S 67
2 A 2017-11-26 10H 10M 2S 30
3 B 2017-11-26 9H 15M 36S 28
4 B 2017-11-29 9H 50M 55S 90
我需要基于第二个数据集为此数据集中的每一行添加两个新变量(纬度和经度),使用列“id”、“date”和“time”作为创建新列的条件.
但是,两个数据集之间的“时间”并不完全相同,因此我需要这个条件是一个近似值(即最近的 'time' 可用于给定的 'id' 和'date')。另一个问题是第二个数据集有更多的行,因此,通过选择 'nearest time',一些行将在添加到第一个数据集时被忽略。
请参阅第二个数据集的示例:
id <- c("A", "A", "A", "B", "B", "B")
date <- ymd(c("2017-11-26", "2017-11-26", "2017-11-30", "2017-11-26",
"2017-11-26", "2017-11-29"))
time <- hms(c("09:00:00", "10:00:00", "08:00:00", "09:00:00",
"13:00:00", "10:00:00"))
lat <- c(-30.6456, -29.5648, -27.6667, -31.5587, -30.6934, -29.3147)
long <- c(-50.4879, -49.8715, -51.8716, -50.4456, -50.9842, -51.9787)
df2 <- tibble(id, date, time, lat, long)
df2
# A tibble: 6 x 5
id date time lat long
<chr> <date> <Period> <dbl> <dbl>
1 A 2017-11-26 9H 0M 0S -30.6 -50.5
2 A 2017-11-26 10H 0M 0S -29.6 -49.9
3 A 2017-11-30 8H 0M 0S -27.7 -51.9
4 B 2017-11-26 9H 0M 0S -31.6 -50.4
5 B 2017-11-26 13H 0M 0S -30.7 -51.0
6 B 2017-11-29 10H 0M 0S -29.3 -52.0
因此,我首先需要按“id”分组,然后按“日期”分组,然后提取数据集2中的“lat”和“long”作为数据集1中最近的“时间”,创建数据集 1.
中的两个新列
生成的数据集如下所示:
df_output
# A tibble: 4 x 6
id date time variable1 lat long
<chr> <date> <Period> <chr> <dbl> <dbl>
1 A 2017-11-26 9H 25M 30S 67 -30.6 -50.5
2 A 2017-11-26 10H 10M 2S 30 -29.6 -49.9
3 B 2017-11-26 9H 15M 36S 28 -31.6 -50.4
4 B 2017-11-29 9H 50M 55S 90 -29.3 -52.0
我试过 group_by()、map2_dfr()、merge()、left_join()、case_when() 等。但是找不到如何执行此操作。
您可以使用data.table
喜欢
library(data.table)
df <- df %>%
mutate(time = paste(date, time) %>% ymd_hms()) %>%
select(-date)
df2 <- df2 %>%
mutate(time = paste(date, time) %>% ymd_hms()) %>%
select(-date)
df <- data.table(df, key = c("id", "time"))
df2 <- data.table(df2, key = c("id", "time"))
df2[df, list(id, time, variable1, lat, long), roll = "nearest"]
id time variable1 lat long
1: A 2017-11-26 09:25:30 67 -30.6456 -50.4879
2: A 2017-11-26 10:10:02 30 -29.5648 -49.8715
3: B 2017-11-26 09:15:36 28 -31.5587 -50.4456
4: B 2017-11-29 09:50:55 90 -29.3147 -51.9787
我不确定 variable1
的情况,为什么在您的问题中 df
和 df_output
是不同的。
我在下面举例说明了这个数据集:
library(lubridate)
library(tidyverse)
id <- c("A", "A", "B", "B")
date <- ymd(c("2017-11-26", "2017-11-26", "2017-11-26", "2017-11-29"))
time <- hms(c("09:25:30", "10:10:02", "09:15:36", "9:50:55"))
variable1 <- c("67", "30", "28", "90")
df <- tibble(id, date, time, variable1)
df
A tibble: 4 x 4
id date time variable1
<chr> <date> <Period> <chr>
1 A 2017-11-26 9H 25M 30S 67
2 A 2017-11-26 10H 10M 2S 30
3 B 2017-11-26 9H 15M 36S 28
4 B 2017-11-29 9H 50M 55S 90
我需要基于第二个数据集为此数据集中的每一行添加两个新变量(纬度和经度),使用列“id”、“date”和“time”作为创建新列的条件.
但是,两个数据集之间的“时间”并不完全相同,因此我需要这个条件是一个近似值(即最近的 'time' 可用于给定的 'id' 和'date')。另一个问题是第二个数据集有更多的行,因此,通过选择 'nearest time',一些行将在添加到第一个数据集时被忽略。
请参阅第二个数据集的示例:
id <- c("A", "A", "A", "B", "B", "B")
date <- ymd(c("2017-11-26", "2017-11-26", "2017-11-30", "2017-11-26",
"2017-11-26", "2017-11-29"))
time <- hms(c("09:00:00", "10:00:00", "08:00:00", "09:00:00",
"13:00:00", "10:00:00"))
lat <- c(-30.6456, -29.5648, -27.6667, -31.5587, -30.6934, -29.3147)
long <- c(-50.4879, -49.8715, -51.8716, -50.4456, -50.9842, -51.9787)
df2 <- tibble(id, date, time, lat, long)
df2
# A tibble: 6 x 5
id date time lat long
<chr> <date> <Period> <dbl> <dbl>
1 A 2017-11-26 9H 0M 0S -30.6 -50.5
2 A 2017-11-26 10H 0M 0S -29.6 -49.9
3 A 2017-11-30 8H 0M 0S -27.7 -51.9
4 B 2017-11-26 9H 0M 0S -31.6 -50.4
5 B 2017-11-26 13H 0M 0S -30.7 -51.0
6 B 2017-11-29 10H 0M 0S -29.3 -52.0
因此,我首先需要按“id”分组,然后按“日期”分组,然后提取数据集2中的“lat”和“long”作为数据集1中最近的“时间”,创建数据集 1.
中的两个新列生成的数据集如下所示:
df_output
# A tibble: 4 x 6
id date time variable1 lat long
<chr> <date> <Period> <chr> <dbl> <dbl>
1 A 2017-11-26 9H 25M 30S 67 -30.6 -50.5
2 A 2017-11-26 10H 10M 2S 30 -29.6 -49.9
3 B 2017-11-26 9H 15M 36S 28 -31.6 -50.4
4 B 2017-11-29 9H 50M 55S 90 -29.3 -52.0
我试过 group_by()、map2_dfr()、merge()、left_join()、case_when() 等。但是找不到如何执行此操作。
您可以使用data.table
喜欢
library(data.table)
df <- df %>%
mutate(time = paste(date, time) %>% ymd_hms()) %>%
select(-date)
df2 <- df2 %>%
mutate(time = paste(date, time) %>% ymd_hms()) %>%
select(-date)
df <- data.table(df, key = c("id", "time"))
df2 <- data.table(df2, key = c("id", "time"))
df2[df, list(id, time, variable1, lat, long), roll = "nearest"]
id time variable1 lat long
1: A 2017-11-26 09:25:30 67 -30.6456 -50.4879
2: A 2017-11-26 10:10:02 30 -29.5648 -49.8715
3: B 2017-11-26 09:15:36 28 -31.5587 -50.4456
4: B 2017-11-29 09:50:55 90 -29.3147 -51.9787
我不确定 variable1
的情况,为什么在您的问题中 df
和 df_output
是不同的。