#r #loops #merge
#r #циклы #слияние
Вопрос:
Я извлек частичную информацию из двух фреймов данных, как показано ниже:
df1 <- data.frame(sample=c(1, 2, 3, 4, 5),
RT=c(3.88, 4.52, 32.82, 15.71, 20.33),
Hit=c(2, 1, 7, 1, 5))
и
df2 <- data.frame(rt_stand=c(4.5, 8.5, 15.8, 23.2, 35.0),
n_carb=c(10, 11, 12, 13, 14),
below=c(5.5, 6.8, 8.2, 10.0, 12.3))
Я бы хотел, чтобы строки из df2 соединялись со строками df1 на основе ближайшего, но меньшего значения.
Выводом будет фрейм данных как таковой:
пример | RT | Удар | rt_stand | n_carb | ниже |
---|---|---|---|---|---|
1 | 3.88 | 2 | NA | NA | NA |
2 | 4.52 | 1 | 4.5 | 10 | 5.5 |
3 | 32.82 | 7 | 23.2 | 13 | 10.0 |
4 | 15.71 | 1 | 8.5 | 11 | 6.8 |
5 | 20.33 | 5 | 15.8 | 12 | 8.2 |
Выше приведен небольшой воспроизводимый пример. Я считаю, что для работы со всем набором данных мне нужно будет создать цикл, который связывает / объединяет строки df2 с df1 на основе функции, которая находит минимальное, но меньшее число.
Любая помощь будет с благодарностью принята.
Комментарии:
1. Ближайшее, но меньшее значение какой переменной? Вы сравниваете
RT
ofdf1
сrt_stand
ofdf2
?2. Скользящее соединение? Я не слишком понимаю логику, которую вы ожидаете:
library(data.table); setDT(df1); setDT(df2); df2[df1, on="rt_stand==RT", roll=TRUE]
Ответ №1:
Вы можете использовать fuzzyjoin
package для хранения строк, где RT
больше, чем rt_stand
и для каждого sample
сохранить ближайшее значение.
library(dplyr)
fuzzyjoin::fuzzy_inner_join(df1, df2, by = c('RT' = 'rt_stand'),
match_fun = `>`) %>%
arrange(sample, rt_stand) %>%
group_by(sample) %>%
slice(n()) %>%
ungroup -> result
result
# A tibble: 4 x 6
# sample RT Hit rt_stand n_carb below
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 2 4.52 1 4.5 10 5.5
#2 3 32.8 7 23.2 13 10
#3 4 15.7 1 8.5 11 6.8
#4 5 20.3 5 15.8 12 8.2
Обратите внимание, что вышеупомянутое result
не имеет sample = 1
, поскольку нет RT
значения, которое было бы больше, чем rt_stand
для этого sample
. Чтобы получить все sample
значения, которые вы можете затем выполнить :
df1 %>%
filter(!sample %in% result$sample) %>%
bind_rows(result)
# sample RT Hit rt_stand n_carb below
#1 1 3.88 2 NA NA NA
#2 2 4.52 1 4.5 10 5.5
#3 3 32.82 7 23.2 13 10.0
#4 4 15.71 1 8.5 11 6.8
#5 5 20.33 5 15.8 12 8.2
Комментарии:
1. Большое вам спасибо. Это отлично сработало, и fuzzyjoin чрезвычайно полезен!