我试图从数据框(df1
)中提取索引值,该数据框表示一系列时间(开始 - 结束)并包含另一个数据帧(df2
)中给出的时间。我所需的输出是df3
。
df1<-data.frame(index=c(1,2,3,4),start=c(5,10,15,20),end=c(10,15,20,25))
df2<-data.frame(time=c(11,17,18,5,5,22))
df3<-data.frame(time=c(11,17,18,5,5,22),index=c(2,3,3,1,1,4))
这有解决方案吗?
答案 0 :(得分:1)
您可以使用R基本功能执行此操作。 which
sapply
内部 inds <- apply(df1[,-1], 1, function(x) seq(from=x[1], to=x[2]))
index <- sapply(df2$time, function(x){
tmp <- which(x == inds, arr.ind = TRUE);
tmp[, "col"]
} )
df3 <- data.frame(df2, index)
df3
time index
1 11 2
2 17 3
3 18 3
4 5 1
5 5 1
6 8 1
和逻辑比较的组合将为您完成工作。
Use Strict Mode for Redirect URIs
答案 1 :(得分:1)
数据:
df1<-data.frame(index=c(1,2,3,4),start=c(5,10,15,20),end=c(10,15,20,25))
df2<-data.frame(time=c(11,17,18,2,5,5,8,22))
代码:
# get index values and assign it to df2 column
df2$index <- apply( df2, 1, function(x) { with(df1, index[ x[ 'time' ] >= start & x[ 'time' ] <= end ] ) })
输出:
df2
# time index
# 1 11 2
# 2 17 3
# 3 18 3
# 4 2
# 5 5 1
# 6 5 1
# 7 8 1
# 8 22 4
答案 2 :(得分:1)
以下是findInterval
ftx <- function(x, y) findInterval(x, y)
df3 <- transform(df2, index = pmax(ftx(time, df1$start), ftx(time, df1$end)))
df3
# time index
#1 11 2
#2 17 3
#3 18 3
#4 5 1
#5 5 1
#6 22 4
或其他选项foverlaps
来自data.table
library(data.table)
dfN <- data.table(index = seq_len(nrow(df2)), start = df2$time, end = df2$time)
setDT(df1)
setkey(dfN, start, end)
setkey(df1, start, end)
foverlaps(dfN, df1, which = TRUE)[, yid[match(xid, dfN$index)]]
#[1] 2 3 3 1 1 4
由于OP评论使用管道解决方案,@ Jilber Urbina的解决方案可以通过tidyverse
函数实现
library(tidyverse)
df1 %>%
select(from = start, to = end) %>%
pmap(seq) %>%
do.call(cbind, .) %>%
list(.) %>%
mutate(df2, new = .,
ind = map2(time, new, ~ which(.x == .y, arr.ind = TRUE)[,2])) %>%
select(-new)
# time ind
#1 11 2
#2 17 3
#3 18 3
#4 5 1
#5 5 1
#6 22 4