2

我是一个绝对的初学者,我希望有人能够帮助我解决我今晚大部分时间都被困在的合并问题,并且迄今为止无法成功地将解决方案适应这个特定示例的类似问题。

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

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)

在 vkey 的值介于变量 vlo 和 vhi 之间的情况下,我想输出一个包含 dumdata 数据的新数据帧。实际上,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
4

3 回答 3

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)
于 2013-10-01T15:05:21.910 回答
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
于 2013-10-01T14:43:34.367 回答
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
于 2013-10-01T15:38:47.650 回答