基于矢量键合并数据帧

时间:2013-10-01 14:35:46

标签: r merge dataframe

我是一个绝对的初学者,我希望有人能够帮助我解决我今晚大部分时间一直困扰的合并问题,并且到目前为止还无法成功解决类似问题的解决方案。特别的例子。

我制作了一个虚拟数据框和向量来帮助说明我的问题:

dumdata <- data.frame(id=c(1:5), pcode=c(1234,9876,4477,2734,3999), vlo=c(100,450,1000,1325,1500), vhi=c(300,950,1100,1450,1700))

id pcode  vlo  vhi
 1  1234  100  300
 2  9876  450  950
 3  4477 1000 1100
 4  2734 1325 1450
 5  3999 1500 1700


vkey <- c(105,290,513,1399,1572,1683)

我想输出一个包含dumdata数据的新数据帧,其中vkey的值介于变量vlo和vhi之间。在实践中,vkey的值总是落在vlo-vhi范围之间,并且范围总是离散的。

所需的输出如下所示:

id   pcode   vlo   vhi  vkey
 1    1234   100   300   105
 1    1234   100   300   290
 2    9876   450   950   513
 4    2734  1325  1450  1399
 5    3999  1500  1700  1572
 5    3999  1500  1700  1683

3 个答案:

答案 0 :(得分:4)

您可以使用for一次性构建整个索引向量,而不是使用sapply循环。

ind <- sapply(vkey, function(x) which(dumdata$vlo < x & x < dumdata$vhi))
data.frame(dumdata[ind,], vkey)

    id pcode  vlo  vhi vkey
1    1  1234  100  300  105
1.1  1  1234  100  300  290
2    2  9876  450  950  513
4    4  2734 1325 1450 1399
5    5  3999 1500 1700 1572
5.1  5  3999 1500 1700 1683

如果vkey中的任何值与dumdata中的多行相匹配,那么它会变得更加丑陋,因为您需要使用lapply代替sapply然后执行

data.frame(dumdata[unlist(ind),], rep(vkey, sapply(vkey, length)))

返回所有匹配项,但我从示例中看出它不会发生。

修改

为了完整性,我将补充说您也可以使用mapply,但这主要是针对您需要与多个变量进行比较的情况(例如,如果您有vkey1和需要满足条件的vkey2

ind <- mapply(function(x, y) which(dumdata$vlo < x & y < dumdata$vhi),
              vkey1, vkey2)

答案 1 :(得分:2)

使用data.table包。

library(data.table)

# added a blank vkeyvalue column
dumdata <- data.table(
   id=c(1:5), 
   pcode=c(1234,9876,4477,2734,3999), 
   vlo=c(100,450,1000,1325,1500), 
   vhi=c(300,950,1100,1450,1700),
   vkeyvalue = as.integer(NA)
)

#initialising the final dataset being populated with the same structure as dumdata
finalfiltereddata <- dumdata[0]
vkey <- c(105,290,513,1399,1572,1683)

# looping throug each key
for ( i in vkey)
{
#subsetting dumdata for values which meet the condition vlo < i & vhi > i
filtereddata <- dumdata[vlo < i & vhi > i]

#assigning the filtered data the respective vkeyvalue
filtereddata[, vkeyvalue := as.integer(i)]

#appending to the master data set
finalfiltereddata <- rbind(finalfiltereddata, filtereddata)
}

finalfiltereddata

   # id pcode  vlo  vhi vkeyvalue
# 1:  1  1234  100  300       105
# 2:  1  1234  100  300       290
# 3:  2  9876  450  950       513
# 4:  4  2734 1325 1450      1399
# 5:  5  3999 1500 1700      1572
# 6:  5  3999 1500 1700      1683

答案 2 :(得分:1)

一个选项可能是使用cut为“vkey”变量创建匹配的“id”列,如下所示:

cutBreaks <- sort(unlist(dumdata[c("vlo", "vhi")], use.names = FALSE))
cutLabels <- rep(1:nrow(dumdata), each = 2) * c(1, -1)

new <- data.frame(vals = vkey, id = cut(vkey, breaks = cutBreaks, 
                                        labels = cutLabels[-length(cutLabels)]))
new
#   vkey id
# 1  105  1
# 2  290  1
# 3  513  2
# 4 1399  4
# 5 1572  5
# 6 1683  5

完成后,merge应该没有问题:

merge(new, dumdata)
#   id vkey pcode  vlo  vhi
# 1  1  105  1234  100  300
# 2  1  290  1234  100  300
# 3  2  513  9876  450  950
# 4  4 1399  2734 1325 1450
# 5  5 1572  3999 1500 1700
# 6  5 1683  3999 1500 1700