【问题标题】:Fast way to compare multiples values across dataframes in R在 R 中跨数据帧比较多个值的快速方法
【发布时间】:2016-02-23 03:47:52
【问题描述】:

这是this question 的后续行动,人们发现它有一个不好的例子。尽管如此,它还是得到了一个相当好的解决方案,但它仍然非常慢。

我希望有更快的方法;

可重现的示例(我知道它看起来很奇怪,但它确实有效)

set.seed(1)
class <- sample(LETTERS, 15)
origpat <- data.table(c(rep(sample(1:100),3), rep(sample(1:500), 4), sample(1:600), sample(200:299)))
set.seed(3)
refpat <- data.table(rep(seq(1,600,1),5))

dt <- data.table(rep.int(1:600,3))
dt$class <- rep(sample(LETTERS, 15),120)
dt <- dt[order(dt$V1, ascending = T)]
setnames(dt, "V1", "pnum")

df <- data.table(origpat, refpat)
colnames(df) <- c("origpat","refpat")
setkey(df, origpat)
df[, idx := .I] # you might get warning but ignore

所以我们有两个 data.frames:df 包含两行 origpatrefpatdt 包含一列 pnum,它捕获与分配相同的数字 origpatclass每个pnum 到三个班级。

我想找到最快的方法来比较dt 中的类与df 中的两个专利origpatrefpat 之间的重叠(或其他一些比较度量)。

这提供了一个可行的解决方案L

df[,compare := {x = dt[pnum== origpat, class]; y = dt[pnum == refpat, class]; sum(x %in% y)}, by = idx]

这个解决方案的问题是它看起来很快但真正的数据集

  • 包含超过 22 个 MIO 行
  • 拥有超过 92,000 个 pnum 和超过 5,000 个 class 元素
  • 每个专利的 class 元素数量在 1 到 26 之间变化
  • 不确定这是否会有所不同,但 pnumorigpatrefpat 是字符,而不是数字。

出于一般目的,xy 应该有可能在不同的数据集中找到(因此不是在 dt 中都存在,并且该解决方案应该适用于大数据集。应用于我的数据的当前解决方案大约需要100 行需要 1 分钟。我有 2000 万行,所以需要很长时间。

希望这提供了一个合理的可重现示例,以便找到一个好的解决方案

【问题讨论】:

  • df中,你有两列同名,每一行都是相同的(因为你有ordered/setkey origpat & refpat)。这似乎很奇怪
  • 更正这不是应该的样子。会更新
  • 对不起,你错了。会立即改变
  • 不,origpat 和 refpat 列的长度相同。 sum(x == y) 旨在捕获 x 和 y 中重叠元素的数量(在此示例中为 class)。使用我目前正在运行的sum(x %in% y) 可能会更好
  • 我会考虑这一点,但只是为了澄清一下 - 这是与您之前链接的问题不同的问题,对吧?特别是df 这里没有“class”/“mainprim”列。

标签: r data.table memory-efficient


【解决方案1】:

这是一种通过重写循环使其更快的简单方法,但我仍然对这个问题感到有些模糊:

setkey(dt, pnum)
df[, compare := {x = dt[.(origpat), class];
                 dt[.(refpat), sum(x %in% class), by = .EACHI]$V1}
   , by = origpat]

【讨论】:

  • 我正在尝试完成这项工作,但它没有。 origpatrefpat 这里是指单独的对象还是df 的列名?
  • 我得到这个错误:错误在 vecseq(f__, len__, if (allow.cartesian || notjoin || !anyDuplicated(f__, : Join results in 442953 rows; more than 279302 = nrow(x )+nrow(i). 检查 i 中的重复键值,每个键值都加入 x 中的同一组。如果没问题,请尝试 by=.EACHI 为每个组运行 j 以避免大分配。如果您确定要继续,请使用 allow.cartesian=TRUE 重新运行。否则,请在 FAQ、Wiki、Stack Overflow 和 datatable-help 中搜索此错误消息以获取建议。allow.cartesian = T 不会改变任何内容
  • 在执行setkey(dt, pnum) 之后,我的代码速度达到了 100 倍。不幸的是,我按下了错误的按钮并且未能保存结果(它在不到两个小时的时间内完成了 2 个 MIO 行)。现在我无法恢复那个速度。不知道发生了什么 :((((
  • 好吧,我想通了后者。将ref.pat 保存为数字而不是字符会显着提高速度
  • 对字符使用%chin% 以提高速度 - 在数字上应该非常接近%in%
猜你喜欢
  • 2022-11-10
  • 2012-04-22
  • 1970-01-01
  • 2013-01-19
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 2012-09-16
相关资源
最近更新 更多