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

基于其他值之间的值合并两个数据库

  •  0
  • elliot  · 技术社区  · 6 年前

    我想使用一个数据帧中的一个类别,并基于一个类似的列(合并)将其应用到另一个。但是,合并需要考虑在两列之间找到的一系列数据点。下面我举一个例子。

    set.seed(123)  
    
    df_1 <- tibble(
      x = c(0, 500, 1000, 1500, 2000),
      y = c(499, 999, 1499, 1999, 99999),
      desc = LETTERS[1:5]
    )
    
        > df_1
    # A tibble: 5 x 3
          x     y desc 
      <dbl> <dbl> <chr>
    1     0   499 A    
    2   500   999 B    
    3  1000  1499 C    
    4  1500  1999 D    
    5  2000 99999 E 
    
    df_2 <- tibble(
      code = sample(1:2500,5,F)
    )
    
     >df_2
    # A tibble: 5 x 1
           code
          <int>
        1   719
        2  1970
        3  1022
        4  2205
        5  2348
    
    ## desired output
    
    
    df_2 %>% 
      mutate(desc = c('B', 'D', 'C', 'E', 'E'))
    # A tibble: 5 x 2
       code desc 
      <int> <chr>
    1   719 B    
    2  1970 D    
    3  1022 C    
    4  2205 E    
    5  2348 E  
    

    x y . 有什么想法吗?

    3 回复  |  直到 6 年前
        1
  •  1
  •   AntoniosK    6 年前
    library(tidyverse)
    
    set.seed(123)  
    
    df_1 <- tibble(
      x = c(0, 500, 1000, 1500, 2000),
      y = c(499, 999, 1499, 1999, 99999),
      desc = LETTERS[1:5]
    )
    
    df_2 <- tibble(
      code = sample(1:2500,5,F)
    )
    
    
    df_1 %>%
      mutate(code = map2(x, y, ~seq(.x, .y, 1))) %>%  # create a sequence of numbers with step = 1
      unnest() %>%                                    # unnest data
      inner_join(df_2, by="code") %>%                 # join df_2 
      select(-x, -y)                                  # remove columns
    
    # # A tibble: 5 x 2
    #   desc   code
    #   <chr> <dbl>
    # 1 B       719
    # 2 C      1022
    # 3 D      1970
    # 4 E      2205
    # 5 E      2348
    
        2
  •  2
  •   Tim Biegeleisen    6 年前

    这是一个在SQL中很容易处理的问题,因此一个选择是使用 sqldf 包,使用此查询:

    SELECT t2.code, COALESCE(t1.desc, '') AS desc
    FROM df_2 t2
    LEFT JOIN df_1 t1
        ON t2.code BETWEEN t1.x AND t1.y;
    

    R代码:

    library(sqldf)
    sql <- paste0("SELECT t2.code, COALESCE(t1.desc, '') AS desc ",
                  "FROM df_2 t2 LEFT JOIN df_1 t1 ON t2.code BETWEEN t1.x AND t1.y")
    result <- sqldf(sql)
    
        3
  •  0
  •   Frank    6 年前

    这似乎有效,但不是很整洁:

    df_2 %>% mutate(v = with(df_1, desc[ findInterval(code, x) ]))
    
      code v
    1  719 B
    2 1970 D
    3 1022 C
    4 2205 E
    5 2348 E
    

    这只使用 x 列,所以假设范围内没有间隙( y ).