Использование dplyr для выбора диапазона на основе группирующей переменной в отдельном data.frame - PullRequest
1 голос
/ 05 февраля 2020

Я хочу нарезать data.frame, содержащий нерегулярно выбранные временные ряды, основанные на коэффициенте группировки и диапазоне временных интервалов в отдельном data.frame. Я делаю это с al oop сейчас действительно неэлегентным способом. Я пытался поправиться с аккуратным синтаксисом и задавался вопросом, есть ли более элегантный подход для получения res из foo и bar.

foo <- data.frame(x=seq(1,100,by=2),y=rnorm(n=50)) 
# foo$x would actually be less regular in the real data
bar <- data.frame(ID=c("Stage_1","Stage_2","Stage_3","Stage_4"),
                  xMin = c(10,32,54,85),
                  xMax = c(17,50,76,89))
res <- data.frame()
for(i in 1:nlevels(bar$ID)){
  xMin <- bar$xMin[bar$ID==levels(bar$ID)[i]]
  xMax <- bar$xMax[bar$ID==levels(bar$ID)[i]]

  xMinIndex <- findInterval(xMin,foo$x) #could fuss inner and outer search
  xMaxIndex <- findInterval(xMax,foo$x)

  tmp <- foo[xMinIndex:xMaxIndex,]
  tmp$ID <- levels(bar$ID)[i]
  res <- rbind(res,tmp)
}
res

Любые советы приветствуются.

1 Ответ

1 голос
/ 05 февраля 2020

Вот вариант с Map

res1 <- do.call(rbind, Map(function(x, y, z) 
   data.frame(foo[x:y,], ID = as.character(z), stringsAsFactors = FALSE),
     findInterval(bar$xMin, foo$x),
        findInterval(bar$xMax, foo$x), bar$ID))
all.equal(res1, res)
#[1] TRUE

Или с использованием data.table

library(data.table)
setDT(foo)[bar,  on = .(x >= xMin, x <= xMax)]

Или с использованием tidyverse

library(dplyr)
library(purrr)
library(tidyr)
bar %>% 
    transmute(ID, col1 = map2(findInterval(xMin, foo$x),  
                               findInterval(xMax, foo$x),  ~
                         foo %>% slice(.x:.y))) %>% 
    unnest(c(col1))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...