【问题标题】:r compare two data.tables by rowr 按行比较两个data.tables
【发布时间】:2019-07-11 16:27:28
【问题描述】:

我有两个要比较的 data.tables。

但不知道为什么会有警告

DT1 <- data.table(ID=c("F","A","E","B","C","D","C"),
                  num=c(59,3,108,11,22,54,241),
                  value=c(90,47,189,38,42,86,280),
                  Mark=c("Mary","Tom","Abner","Norman","Joanne",
                  "Bonnie","Trista"))

DT2 <- data.table(Mark=c("Mary","Abner","Bonnie","Trista","Norman"),
                  numA=c(48,20,88,237,20),
                  numB=c(60,326,54,268,89),
                  valueA=c(78,34,78,270,59),
                  valueB=c(90,190,90,385,75))

DToutput <- DT1[(num > DT2$numA & num < DT2$numB &
                value > DT2$valueA & value < DT2$valueB)]

我的目标

我想根据DT1中的Mark来找到numvalue,而numAnumBDT2中有一个范围。

例如

对于DT1num = 59value = 90 以及Mark = "Mary" 中的行F。所以,在使用by=Mary时,还必须匹配:

num(59) &gt; DT2$numA(48) &amp; num(59) &lt; DT2$numB(60) &amp; value(90) &gt; DT2$valueA(78) &amp; value(90) &lt; DT2$valueB(90)

你可以看到90 &lt; 90不成立,所以我的结果不会有行F

我收到了这个警告:

Warning messages:
 1: In num > DT2$numA : longer object length is not a multiple of shorter object lengt
 2: In num < DT2$numB : longer object length is not a multiple of shorter object lengt
 3: In value > DT2$valueA : longer object length is not a multiple of shorter object lengt
 4: In value < DT2$valueB : longer object length is not a multiple of shorter object lengt

如何修改它以完成我想做的事情?

谢谢

补充:DT2中可以使用多个相同的Marks,但取值范围不同。这会影响比较吗?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    另一个使用非等内连接的选项:

    DT2[DT1, on=.(Mark=Mark, numA<num, numB>num, valueA<value, valueB>value), nomatch=0L, 
        .(ID, num, value, Mark)]
    

    或:

    DT1[DT2, on=.(Mark, num>numA, num<numB, value>valueA, value<valueB), nomatch=0L, 
        .(ID, num=x.num, value=x.value, Mark)]
    

    输出:

       ID num value   Mark
    1:  E 108   189  Abner
    2:  C 241   280 Trista
    

    【讨论】:

    【解决方案2】:

    这通常是您要寻找的吗?我加入了数据表并根据您的条件使用between 进行过滤。如果这不是您想要的,您可以发布您预期输出的数据表吗?

    library(data.table)
    
    DT1[DT2, on = "Mark"][between(num, numA, numB, incbounds = F) & between(value, valueA, valueB, incbounds = F)]
    
       ID num value   Mark numA numB valueA valueB
    1:  E 108   189  Abner   20  326     34    190
    2:  C 241   280 Trista  237  268    270    385
    

    编辑: 这种方法与@Chinsoon12 的非等内连接之间的基准比较表明,非等内连接速度更快,甚至更多数据。这不是一个完美的基准(只是重复了data.table),但我仍然认为很明显非等内连接效率更高。

    Unit: milliseconds
               expr      min       lq      mean    median       uq      max neval
            between 233.6378 265.4323 303.14039 301.82455 334.3225 373.2760    10
     non_equi_inner  71.6925  74.1547  96.96584  91.14375  97.6664 179.9907    10
    

    基准代码:

    DT1 <- data.table(sapply(DT1, rep, 1e3))[, c("num", "value") := lapply(.SD, as.integer), .SDcols = c("num", "value")]
    DT2 <- data.table(sapply(DT2, rep, 1e3))[, c("numA", "numB", "valueA", "valueB") := lapply(.SD, as.integer), .SDcols = c("numA", "numB", "valueA", "valueB")]
    
    microbenchmark::microbenchmark(
      between = {
        DT1[DT2, on = "Mark", allow.cartesian = T][between(num, numA, numB, incbounds = F) & between(value, valueA, valueB, incbounds = F)]
    
      },
      non_equi_inner = {
        DT1[DT2, on=.(Mark, num>numA, num<numB, value>valueA, value<valueB), nomatch=0L, 
            .(ID, num=x.num, value=x.value, Mark), allow.cartesian = T]
      },
      times = 10
    
    )
    

    【讨论】:

    • 谢谢,这是我想要的结果,但是我把这个程序应用到了别的地方,出了点问题。也许我的其他文件 DT2 重复次数过多(正如我的问题所补充的那样),也许它是原始文件。信息太多,我按照建议加了allow.cartesian=TRUE,但是显示error:unused argument (incbounds = FALSE),不知道大家有什么想法?
    • 以下是部分错误片段: 检查 i 中的重复键值,每个键值都一遍又一遍地加入 x 中的同一组。如果没问题,请尝试 by=.EACHI 为每个组运行 j 以避免大量分配。您确定要继续,请使用 allow.cartesian=TRUE 重新运行。
    • 两个问题:1) 此代码是否适用于您机器上的示例? 2) 第一个括号看起来像这样:DT1[DT2, on = "Mark", allow.cartesian = T]?还是allow.cartesian = T 在其他地方?
    • 1.此代码可用于我的 DT1 和 DT2 示例,但不能用于其他材料。 2.我修改为DT1[DT2, on = "Mark", allow.cartesian = T] 反而显示error:unused argument (incbounds = F)
    • 我在做 退出当前的R会话,很正常,非常感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多