Как вернуть диапазон значений, разделенных между двумя фреймами данных в R?

У меня есть несколько фреймов данных с одинаковыми именами столбцов, и ID , следующие являются началом from и концом to диапазона и group меткой каждого из них.

Я хочу найти, какие значения from и to из одного из data frames входят в диапазон другого. Я оставляю пример изображения, чтобы проиллюстрировать, чего я хочу достичь (на данный момент график не нужен)

Как вернуть диапазон значений, разделенных между двумя фреймами данных в R?

Я думал, что смогу сделать это, используя between() из dplyr package, но нет. Этого можно добиться, если between() возвращает true, а затем возвращает максимальное значение from и минимальное значение to между фреймами данных.

Я оставляю примеры кадров данных и results, которые я хочу получить.

a <- data.frame(ID = c(1,1,1,2,2,2,3,3,3),from=c(1,500,1000,1,500,1000,1,500,1000),
                to=c(400,900,1400,400,900,1400,400,900,1400),group=rep("a",9))
b <- data.frame(ID = c(1,1,1,2,2,2,3,3,3),from=c(300,1200,1900,1400,2800,3700,1300,2500,3500),
                to=c(500,1500,2000,2500,3000,3900,1400,2800,3900),group=rep("b",9))
results <- data.frame(ID = c(1,1,1,2,3),from=c(300,500,1200,1400,1300),
                      to=c(400,500,1400,1400,1400),group=rep("a, b",5))

Я попытался использовать эту функцию, которая вернет мне значения при совпадении, но не вернет мне общий диапазон между ними.

f <- function(vec, id) {
  if (length(.x <- which(vec >= a$from & vec <= a$to & id == a$ID))) .x else NA
}
b$fromA <- a$from[mapply(f, b$from, b$ID)]
b$toA <- a$to[mapply(f, b$to, b$ID)]
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем поиграть с идеей, что начальная и конечная точки находятся в разных столбцах, а диапазоны для одной и той же группы (a и b) не перекрываются. Это мое решение. Я назвал «point_1» и «point_2» вашими мутировавшими «от» и «до» для ясности.

Вы можете связать два кадра данных и сравнить столбец from с предыдущим значением lag(from), чтобы увидеть, меньше ли фактическое значение. Также вы сравниваете предыдущий столбец lag(to) с фактическим столбцом to, чтобы увидеть, перекрывает ли максимальное значение диапазона предыдущий диапазон или нет.

Важно отметить, что эти операции не различают, относятся ли две сравниваемые строки к одной и той же группе (a или b). Поэтому, фильтруя NA в point_1 (новый измененный столбец «из»), вы удалите неправильные измененные значения. Также обратите внимание, что я предполагаю, что, например, диапазон в «a» не может перекрывать две строки в «b». В вашей таблице результатов этого не происходит, но вы должны проверить это в своих кадрах данных.

res = rbind(a,b) %>%  # Bind by rows
  arrange(ID,from) %>% # arrange by ID and starting point (from)
  group_by(ID) %>% # perform the following operations grouped by IDs
# Here is the trick. If the ranges for the same ID and group (i.e. 1,a) do   
# not overlap, when you mutate the following cols the result will be NA for 
# point_1.
  mutate(point_1 = ifelse(from <= lag(to), from, NA),
         point_2 = ifelse(lag(to)>=to, to, lag(to)),
         groups = paste(lag(group), group, sep = ',')) %>% 
  filter(! is.na(point_1)) %>%  # remove NAs in from
  select(ID,point_1, point_2, groups)  # get the result dataframe

Если вы немного поиграете с кодом, не используя filter() и select(), вы увидите, как это работает.

> res
# A tibble: 5 x 4
# Groups:   ID [3]
     ID point_1 point_2 groups
  <dbl>   <dbl>   <dbl> <chr> 
1     1     300     400 a,b   
2     1     500     500 b,a   
3     1    1200    1400 a,b   
4     2    1400    1400 a,b   
5     3    1300    1400 a,b   

Это сделало трюк. Действительно полезный ваш ответ!

Le Paul 07.05.2022 00:39

Другие вопросы по теме