将重叠间隔中的信息包括到data.frame中

将重叠间隔中的信息包括到data.frame中,r,R,我有两个数据帧: dfA " ID from to Lith 1 BG1 0 0.5 SED 2 BG1 0.5 0.6 GDI 3 BG1 0.6 2.8 GRN 3 ZH4 0 0.7 GRN 4 ZH4 0.7 3.0 GDI dfB " ID from to Weath 1 BG1 0 0.8 HW 2 BG1 0.8 1.5 SW 3 BG1 1.5

我有两个数据帧:

dfA
"   ID  from    to  Lith
1   BG1 0       0.5 SED
2   BG1 0.5     0.6 GDI
3   BG1 0.6     2.8 GRN
3   ZH4 0       0.7 GRN
4   ZH4 0.7     3.0 GDI

dfB
"   ID  from    to  Weath
1   BG1 0       0.8 HW
2   BG1 0.8     1.5 SW
3   BG1 1.5     2.6 HW
4   ZH4 0       0.3 HW
5   ZH4 0.3     2.6 SW
我希望dfA中的“Lith”中的信息作为dfB中重叠的百分比(从“to”)。结果应该如下所示:

dfC
"   ID  from    to  Weath   GRN     GDI     SED
1   BG1 0       0.8 HW      0.25    0.125   0.625
2   BG1 0.8     1.5 SW      1       0       0
3   BG1 1.5     2.6 HW      1       0       0
4   ZH4 0       0.3 HW      1       0       0
5   ZH4 0.3     2.6 SW      0.1739  0.8261  0
请注意,dfA的间隔与dfB的间隔不一致,仅应检查相同ID的重叠。此外,请注意,dfB的一个间隔中最多可能有三个重叠。dfA的间隔总是大于dfB


到目前为止,我的尝试已经走到了尽头。按ID拆分df不是一个选项,因为原始数据量是巨大的

I将一次处理一个Lith(GRN、GDI、SED)的每个值,将生成的列添加到
dfC
。对于Lith的每个值,我首先使用
match
函数(这是下面
get.col
函数中的行索引
r
的向量)找到与
dfB
的每一行对应的
dfA
。然后,我将使用
pmax
pmin
以矢量化的方式计算归一化重叠(这很重要,因为您说您有一个大数据集)


get.col这里有一个可能的
foverlaps
解决方案

library(data.table)
setkey(setDT(dfA), ID, from, to)
setkey(setDT(dfB), ID, from, to)
res <- foverlaps(dfA, dfB)[, overlap := (pmin(to, i.to) - pmax(from, i.from))/(to - from)]
dcast(res, ID + from + to + Weath ~ Lith, value.var = "overlap", fill = 0)
#     ID from  to Weath      GDI      GRN   SED
# 1: BG1  0.0 0.8    HW 0.125000 0.250000 0.625
# 2: BG1  0.8 1.5    SW 0.000000 1.000000 0.000
# 3: BG1  1.5 2.6    HW 0.000000 1.000000 0.000
# 4: ZH4  0.0 0.3    HW 0.000000 1.000000 0.000
# 5: ZH4  0.3 2.6    SW 0.826087 0.173913 0.000
库(data.table)
setkey(setDT(dfA),ID,from,to)
setkey(setDT(dfB),ID,from,to)

res合并表格,执行重叠功能,根据需要重塑形状

library(reshape2)
m<-merge(dfB,dfA,by="ID",suffixes=c("",".y"))
overlap<-function(L1,R1,L2,R2) pmax(0,pmin(R1,R2)-pmax(L1,L2))
m$value<-overlap(m$from,m$to,m$from.y,m$to.y)/(m$to-m$from)
dcast(m,ID+from+to+Weath~Lith)

#>    ID from  to Weath      GDI      GRN   SED
#> 1 BG1  0.0 0.8    HW 0.125000 0.250000 0.625
#> 2 BG1  0.8 1.5    SW 0.000000 1.000000 0.000
#> 3 BG1  1.5 2.6    HW 0.000000 1.000000 0.000
#> 4 ZH4  0.0 0.3    HW 0.000000 1.000000    NA
#> 5 ZH4  0.3 2.6    SW 0.826087 0.173913    NA
library(重塑2)
M2 BG1 0.81.5 SW 0.0000001.0000000.000
#>3 BG1 1.5 2.6 HW 0.000000 1.000000 0.000
#>4 ZH4 0.0 0.3 HW 0.000000 1.000000 NA
#>5 ZH4 0.3 2.6 SW 0.826087 0.173913 NA

GRN:0.2/0.8=0.25,GDI:0.1/0.8=0.125,SED:0.5/0.8=0.625->重叠间隔百分比。vecseq(f_uuuuu,len_uuu,if(allow.cartesian | notjoin)中的错误,if(allow.cartesian | notjoin)NULL,else为.integer(max(nrow(x),:Join结果在1619843行中;超过112074=max(nrow(x),nrow(i)).检查i中是否存在重复的键值,每个键值都会一次又一次地加入x中的同一组。如果没有问题,请尝试包括
j
并删除
by
(不包括by)因此,j为每个组运行以避免较大的分配。如果确实要继续,请使用allow.cartesian=TRUE重新运行。否则,请在FAQ、Wiki、Stack Overflow和datatable帮助中搜索此错误消息以获取建议。我没有在此处使用
data.table
s。是否打算将此注释用于?合并到中错误(调用(Ccopy,x)中的错误:作为符号地址传递的空值),因此我尝试了data.table。可能数据集太大了。dcast调用聚合函数。通常情况下,数据集应该没有重复项,但尚未处理。可能我会在处理的数据上尝试您的方法,因为它似乎比Josilber的方法(另一方面,它适用于原始数据)更简单。当存在重复项时,您想做什么?从上下文来看,只对值求和是有效的。因此,您在
dcast
中有一个
aggregate
参数。您可以指定
sum
mean
或其他任何内容。如果需要,您可能需要使用
dcast.data.table
而不是
dcast
使用较旧的
data.table
version似乎可以工作,控制台上显示的行与我想要的一样。但在查看res时,它仍然是长格式的。
library(reshape2)
m<-merge(dfB,dfA,by="ID",suffixes=c("",".y"))
overlap<-function(L1,R1,L2,R2) pmax(0,pmin(R1,R2)-pmax(L1,L2))
m$value<-overlap(m$from,m$to,m$from.y,m$to.y)/(m$to-m$from)
dcast(m,ID+from+to+Weath~Lith)

#>    ID from  to Weath      GDI      GRN   SED
#> 1 BG1  0.0 0.8    HW 0.125000 0.250000 0.625
#> 2 BG1  0.8 1.5    SW 0.000000 1.000000 0.000
#> 3 BG1  1.5 2.6    HW 0.000000 1.000000 0.000
#> 4 ZH4  0.0 0.3    HW 0.000000 1.000000    NA
#> 5 ZH4  0.3 2.6    SW 0.826087 0.173913    NA