【问题标题】:In R: Replacing value of a data frame column by the value of another data frame when between condition is matched在R中:当条件匹配时,将数据框列的值替换为另一个数据框的值
【发布时间】:2015-07-01 22:36:11
【问题描述】:

我有两个数据框:

set.seed(343)
testDF <- data.frame(Score = sample(50, size=50, replace=TRUE), number = rep(letters[1:25],2), Rev = rep(0,50))
sourceDF <- data.frame(min = c(1,10,20,30,40), max = c(9, 19, 29, 39, 50), rev = 1:5)

对于testDF中testDF$score在sourceDF的sourceDF$min和sourceDF$max之间的每一行,将testDF$Rev的值替换为对应的sourceDF$rev。

我让它与两个 for 循环和一个 if 条件一起工作,但它...慢(我的数据集有接近 100 万行)。 我尝试使用 findInterval 没有成功。

有没有更好/更有效的方法来做到这一点?

【问题讨论】:

  • letter 是什么?另外,使用rnorm时请使用set.seed。最后,您的示例不太好,因为Score 永远不会大于9,因此它永远不会落入除第一个之外的任何桶中。我会改用sample
  • 您的示例无法运行。没有称为“字母”的函数。使用 which() 和/或 apply 系列可能会找到更快的解决方案。
  • @TanDollars apply family 不会有任何改善。 which 在这里不太适合 AFIK。
  • 我想答案会在'which()'中找到
  • 9.5 会在哪些数据上出现?它 > 9,所以不在第 1 组,但 ​​Score 数据是一组离散整数还是连续度量?

标签: r dataframe


【解决方案1】:

首先,请参阅我关于如何改进您的问题并使其可重现的评论。其次,这是一种使用data.table::foverlaps快速运行重叠连接的可能方法

library(data.table)
setkey(setDT(testDF)[, Score2 := Score], Score, Score2) # create bounds and key
setkey(setDT(sourceDF), min, max) # Key by min, max
indx <- foverlaps(sourceDF, testDF, nomatch = 0L, which = TRUE) # run foverlaps
testDF[indx$yid,  Rev := sourceDF[indx$xid, rev]] # Update in place by corresponding values

【讨论】:

  • 本质上不就是findInterval(testDF$Score,c(1,10,20,30,40,50))吗?
  • findInterval(testDF$Score,c(1,10,20,30,40,50),rightmost.closed=TRUE) 绝对具体。
  • @thelatemail 你说得对。你可能应该发布这个。我的方法更通用,因为它也适用于多个变量。
【解决方案2】:

感谢您的回答。我想我在没有测试的情况下发布了这个例子太快了。惭愧我... @David 感谢您的指点,我将进一步研究 foverlaps 函数(并将探索更多数据表世界)。

我找到了一个很好的解决方法,而且速度很快。由于我的范围数量有限(示例中为 5 个),我只是使用变量 Score 上的过滤函数(dplyr 库)将 tesdDF 子集为 5 个数据帧。

testDF1 <- filter(testDF, Score>=1 & Score <=9) ## First DF

那么这只是在每个数据帧中分配 Rev 的值的问题。

testDF1$Rev <- sourceDF$rev[1]

这在不到 1 秒的时间内运行,而我在 800k+ 行上的旧循环运行时间为 1h35mn。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-01-31
    • 2022-01-01
    • 1970-01-01
    相关资源
    最近更新 更多