R - 根据第二个数据框中最接近的匹配分配列值

Posted

技术标签:

【中文标题】R - 根据第二个数据框中最接近的匹配分配列值【英文标题】:R - Assign column value based on closest match in second data frame 【发布时间】:2013-11-26 06:53:25 【问题描述】:

我有两个数据框,logger 和 df(时间是数字):

logger <- data.frame(
time = c(1280248354:1280248413),
temp = runif(60,min=18,max=24.5)
)

df <- data.frame(
obs = c(1:10),
time = runif(10,min=1280248354,max=1280248413),
temp = NA
)

我想在 logger$time 中搜索与 df$time 中每一行最接近的匹配项,并将关联的 logger$temp 分配给 df$temp。到目前为止,我已经成功使用了以下循环:

for (i in 1:length(df$time))
closestto<-which.min(abs((logger$time) - (df$time[i])))
df$temp[i]<-logger$temp[closestto]

但是,我现在有很大的数据帧(logger 有 13,620 行,df 有 266138)并且处理时间很长。我读过循环不是最有效的做事方式,但我不熟悉替代方案。有没有更快的方法来做到这一点?

【问题讨论】:

+1 用于带有示例数据的可重现示例,显示您想要什么以及您尝试了什么。顺便说一句 - 下次您使用进行随机抽样的数据时,首先运行命令 set.seed(x),其中 x 是任何整数(大多数人使用 1)。这样,每个复制您的示例的人最终都会得到相同的数据集。 【参考方案1】:

我会为此使用data.table。它使加入keys 变得超级简单和快速。对于您正在寻找的行为,甚至还有一个非常有用的 roll = "nearest" 参数(除了在您的示例数据中没有必要,因为来自 df 的所有 times 都出现在 logger 中)。在下面的示例中,我将df$time 重命名为df$time1,以明确哪个列属于哪个表...

#  Load package
require( data.table )

#  Make data.frames into data.tables with a key column
ldt <- data.table( logger , key = "time" )
dt <- data.table( df , key = "time1" )

#  Join based on the key column of the two tables (time & time1)
#  roll = "nearest" gives the desired behaviour
#  list( obs , time1 , temp ) gives the columns you want to return from dt
ldt[ dt , list( obs , time1 , temp ) , roll = "nearest" ]
#          time obs      time1     temp
# 1: 1280248361   8 1280248361 18.07644
# 2: 1280248366   4 1280248366 21.88957
# 3: 1280248370   3 1280248370 19.09015
# 4: 1280248376   5 1280248376 22.39770
# 5: 1280248381   6 1280248381 24.12758
# 6: 1280248383  10 1280248383 22.70919
# 7: 1280248385   1 1280248385 18.78183
# 8: 1280248389   2 1280248389 18.17874
# 9: 1280248393   9 1280248393 18.03098
#10: 1280248403   7 1280248403 22.74372

【讨论】:

【参考方案2】:

您可以使用data.table 库。这也将有助于提高大数据量的效率 -

library(data.table)

logger <- data.frame(
  time = c(1280248354:1280248413),
  temp = runif(60,min=18,max=24.5)
)

df <- data.frame(
  obs = c(1:10),
  time = runif(10,min=1280248354,max=1280248413)
)

logger <- data.table(logger)
df <- data.table(df)

setkey(df,time)
setkey(logger,time)

df2 <- logger[df, roll = "nearest"]

输出 -

> df2
          time     temp obs
 1: 1280248356 22.81437   7
 2: 1280248360 24.08711  10
 3: 1280248366 22.31738   2
 4: 1280248367 18.61222   5
 5: 1280248388 19.46300   4
 6: 1280248393 18.26535   6
 7: 1280248400 20.61901   9
 8: 1280248402 21.92584   1
 9: 1280248410 19.36526   8
10: 1280248410 19.36526   3

【讨论】:

以上是关于R - 根据第二个数据框中最接近的匹配分配列值的主要内容,如果未能解决你的问题,请参考以下文章

如何为第一个数据帧中匹配的特定列值的所有值获取第二个数据帧的数据?

将时间戳数据与另一个数据集中的最接近时间相匹配。正确矢量化?更快的方式?

根据列值从熊猫数据框中提取行

将列值分配给数据框中的变量

根据相邻列值 Pandas 从列中按第一个或第二个空格提取字符串

返回数据框中最接近用户定义数字的行