我是一个绝对的初学者,我希望有人能够帮助我解决我今晚大部分时间一直困扰的合并问题,并且到目前为止还无法成功解决类似问题的解决方案。特别的例子。
我制作了一个虚拟数据框和向量来帮助说明我的问题:
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
答案 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