代码之家  ›  专栏  ›  技术社区  ›  MLPNPC

与R中的条件合并

  •  2
  • MLPNPC  · 技术社区  · 7 年前
    varA=c('2018-01-03', '2018-01-25','2018-01-15','2018-01-06')
    varB=c('2018-01-02', '2018-01-05', '2018-01-13', '2018-01-21', '2018-01-26')
    varC=c(201801,201802,201804,201809,201815)
    
    df1=as.data.frame(varA)
    df2=as.data.frame(cbind(varB,varC))
    

    使用上述代码获取数据帧:

            varA
    1 2018-01-03
    2 2018-01-25
    3 2018-01-15
    4 2018-01-06
    

            varB   varC
    1 2018-01-02 201801
    2 2018-01-05 201802
    3 2018-01-13 201804
    4 2018-01-21 201809
    5 2018-01-26 201815
    

    由此,我想将df1和df2合并在一起,但条件是,如果varA作为一个日期介于varB的两个日期之间,它将从最早的日期开始使用varC。我认为更容易展示我的预期结果:

           varA    varB         varC
    1 2018-01-03  2018-01-02   201801
    2 2018-01-25  2018-01-21   201809
    3 2018-01-15  2018-01-13   201804
    4 2018-01-06  2018-01-05   201802
    

    希望这是清楚的。我不知道如何获得所需的输出。

    3 回复  |  直到 7 年前
        1
  •  1
  •   Martin Schmelzer    7 年前

    可以使用 data.table :

    varA <- c('2018-01-03', '2018-01-25','2018-01-15','2018-01-06')
    varB <- c('2018-01-02', '2018-01-05', '2018-01-13', '2018-01-21', '2018-01-26')
    varC <- c(201801,201802,201804,201809,201815)
    
    library(lubridate)
    dt1 <- data.table(varA = ymd(varA))
    dt2 <- data.table(varA = ymd(varB), varB = ymd(varB), varC =  varC)
    setkey(dt1, varA)
    setkey(dt2, varA)
    
    dt2[dt1,, roll = T]
    
        2
  •  1
  •   Chris Holbrook    7 年前

    findInterval 在base R中,这可能会有所帮助。例如

    强制VarA和VarB更新对象并使用 findInterval公司 创建一个新列,其中df2中的行(即VarB索引)与您为每个VarA指定的条件相匹配。

    df1$row_match <- findInterval(as.Date(df1$varA), as.Date(df2$varB))
    

    然后创建新的对应列(df2中的行)以加入/合并

    df2$row_match <- seq_len(nrow(df2))
    
    df3 <- merge(df1, df2, by = "row_match")
    #> df3
    #  row_match       varA       varB   varC
    #1         1 2018-01-03 2018-01-02 201801
    #2         2 2018-01-06 2018-01-05 201802
    #3         3 2018-01-15 2018-01-13 201804
    #4         4 2018-01-25 2018-01-21 201809
    
        3
  •  -1
  •   Roman    7 年前

    你可以试试

    library(tidyverse)
    map(df1$varA, function(x)  df2[between(df2$varB, x, x),]) %>% 
      bind_rows() %>% 
      bind_cols(df1,.)
            varA       varB   varC
    1 2018-01-03 2018-01-02 201801
    2 2018-01-25 2018-01-21 201809
    3 2018-01-15 2018-01-13 201804
    4 2018-01-06 2018-01-05 201802
    

    其思想是使用tidyverse函数来寻找区间 map & between ,然后添加 df1