将重叠间隔中的信息包括到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