Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 两个数据帧之间的多次比较,而不使用;至于;_R_Dataframe_Dplyr_Comparison - Fatal编程技术网

R 两个数据帧之间的多次比较,而不使用;至于;

R 两个数据帧之间的多次比较,而不使用;至于;,r,dataframe,dplyr,comparison,R,Dataframe,Dplyr,Comparison,我有两个数据帧(df1和df2),结果是guest\u id、money、和date 我想通过使用这3个参数来确定第一个数据帧中的元素是否也在第二个数据帧中。为此,我希望使用一个变量,我将在df1中添加该变量,并将其命名为match,如果df1中的元素也在df2中,则取1,否则取0 但是,它们并不完全匹配(因为报告中有一些错误),所以我不能简单地通过这3列或类似的内容来合并它们 因此,我想做一些简单的比较,知道: 来宾id比较没有错误,因此我想检查df1的来宾id何时与df2的来宾id匹配 警

我有两个数据帧(
df1
df2
),结果是
guest\u id
money
、和
date

我想通过使用这3个参数来确定第一个数据帧中的元素是否也在第二个数据帧中。为此,我希望使用一个变量,我将在
df1
中添加该变量,并将其命名为
match
,如果
df1
中的元素也在
df2
中,则取1,否则取0

但是,它们并不完全匹配(因为报告中有一些错误),所以我不能简单地通过这3列或类似的内容来合并它们

因此,我想做一些简单的比较,知道:

  • 来宾id比较没有错误,因此我想检查
    df1的
    来宾id
    何时与
    df2的
    来宾id
    匹配
  • 警告:来宾id可能会在数据框中出现多次
  • 当客人在
    df1
    df2
    时,我想检查
    钱和
    日期。我想这样做:
    

    • 对于
      money
      而言,将
      df1
      中的
      钱与
      df2
      中可能出现的所有
      进行区分(但同样仅针对给定的
      来宾id
      )。如果出现接近0的情况(介于-1和1之间,或
      ),我建议先进行左连接,然后应用您的条件并查找df1中的任何原始行是否匹配:

      library('stringr')
      library('dplyr')
      
      df3 <- left_join(df1, df2, by = 'guest_id') %>%
        mutate_at(vars(contains('date')), ymd) %>%
        # Checking for your condition
        mutate(match = (abs(money.x - money.y) < 1) & (abs(date.x - date.y) < 5)) %>%
        # Cleaning data.frame a bit
        select(-money.y, -date.y) %>%
        setNames(str_replace(names(.), '\\.x', '')) %>%
        # Finding if rows had a match
        group_by(guest_id, money, date) %>%
        summarise(match = any(match, na.rm = TRUE))
      
      df3
      

      最新版本的
      data.table
      支持非常方便和高效的非相等联接,尤其是与联接更新和分组方式
      相结合。EACHI

      library(data.table)   # CRAN version 1.10.4 used
      # tolerances
      tol_m <- 1
      tol_d <- 5
      
      data.table(df1)[
        # join with modified df2
        data.table(df2)[
          # create helper columns for non-equi joins
          , `:=`(m1 = money - tol_m, m2 = money + tol_m, 
                 d1 = date - tol_d, d2 = date + tol_d)]
        # non-equi join
        , on = c("guest_id", "money>=m1", "money<=m2", "date>=d1", "date<=d2"), 
        # aggregate group-wise, grouped by join conditions, prettify result
        match := .N, by = .EACHI][, match := as.integer(!is.na(match))][]
      

      如果没有非等联接,我们将不得不创建所有可能组合的笛卡尔积,并消除那些不符合条件的行。

      看看
      fuzzyjoin
      包,尽管我确信使用了两个合并列(其中一个是模糊列,另一个不是)这是可能的。谢谢!乍一看,它似乎确实可以帮助我尝试的Lotineded,而且显然比使用Andrey的方法快得多(尽管两者都很好)。非常感谢!如果
      df1
      df2
      是大对象,如果使用
      setDT()
      而不是
      data.table(),您可以保护内存和时间
      。后者复制时保留原始数据。帧不变,而
      setDT()
      强制到位,即不复制,复制速度更快,但会更改
      df1
      df2
      library('stringr')
      library('dplyr')
      
      df3 <- left_join(df1, df2, by = 'guest_id') %>%
        mutate_at(vars(contains('date')), ymd) %>%
        # Checking for your condition
        mutate(match = (abs(money.x - money.y) < 1) & (abs(date.x - date.y) < 5)) %>%
        # Cleaning data.frame a bit
        select(-money.y, -date.y) %>%
        setNames(str_replace(names(.), '\\.x', '')) %>%
        # Finding if rows had a match
        group_by(guest_id, money, date) %>%
        summarise(match = any(match, na.rm = TRUE))
      
      df3
      
      # A tibble: 6 x 4
      # Groups:   guest_id, money [?]
        guest_id money       date match
           <int> <dbl>     <date> <lgl>
      1        1  10.2 2017-01-01  TRUE
      2        1  10.3 2000-01-01 FALSE
      3        1  50.0 2017-01-01 FALSE
      4        2   9.5 2017-01-01  TRUE
      5        2  10.5 2017-01-01  TRUE
      6        3 100.0 2000-01-01 FALSE
      
      df1 <- structure(list(guest_id = c(1L, 1L, 1L, 2L, 2L, 3L), money = c(10.2, 
      10.3, 50, 10.5, 9.5, 100), date = c("2017-01-01", "2000-01-01", 
      "2017-01-01", "2017-01-01", "2017-01-01", "2000-01-01")), .Names = c("guest_id", 
      "money", "date"), class = "data.frame", row.names = c(NA, -6L
      ))
      
      df2 <- structure(list(guest_id = c(1L, 1L, 2L), money = c(10L, 10L, 
      10L), date = c("2017-01-01", "2015-01-01", "2017-01-03")), .Names = c("guest_id", 
      "money", "date"), class = "data.frame", row.names = c(NA, -3L
      ))
      
      library(data.table)   # CRAN version 1.10.4 used
      # tolerances
      tol_m <- 1
      tol_d <- 5
      
      data.table(df1)[
        # join with modified df2
        data.table(df2)[
          # create helper columns for non-equi joins
          , `:=`(m1 = money - tol_m, m2 = money + tol_m, 
                 d1 = date - tol_d, d2 = date + tol_d)]
        # non-equi join
        , on = c("guest_id", "money>=m1", "money<=m2", "date>=d1", "date<=d2"), 
        # aggregate group-wise, grouped by join conditions, prettify result
        match := .N, by = .EACHI][, match := as.integer(!is.na(match))][]
      
         guest_id money       date match
      1:        1  10.2 2017-01-01     1
      2:        1  10.3 2000-01-01     0
      3:        1  50.0 2017-01-01     0
      4:        2  10.5 2017-01-01     1
      5:        2   9.5 2017-01-01     1
      6:        3 100.0 2000-01-01     0