这是一个玩具的例子。我想比较一下ra
和ev
,前者提供范围(例如时间),后者表示事件发生的时间。
我想在ra
中创建一个新的列hits
,说明每个范围内发生了多少事件。
ra <- data.frame(a=c(0, 250, 500, 750), b=c(250, 500, 750, 900))
ra
a b
1 0 250
2 250 500
3 500 750
4 750 900
ev <- data.frame(events=c(1,1,1,1,1), time=c(100, 200, 450, 550, 600))
ev
events time
1 1 100
2 1 200
3 1 500
4 1 550
5 1 600
这就是结果应该是什么样子。
data.frame(a=c(0, 250, 500, 750), b=c(250, 500, 750, 900), hits=c(2,1,2,0))
a b hits
1 0 250 2
2 250 500 1
3 500 750 2
4 750 900 0
发布于 2019-02-22 03:44:37
ra$hits <- mapply(function(a, b) with(ev, sum(events[time > a & time < b])),
ra$a,ra$b)
ra
# a b hits
# 1 0 250 2
# 2 250 500 1
# 3 500 750 2
# 4 750 900 0
与tidyverse类似的解决方案:
library(tidyverse)
ra$hits <-
pmap(ra, ~ ev %>% summarise(sum(events[between(time, .x, .y)]))) %>%
unlist
或者,使用与arg0naut和akrun的答案类似的逻辑,但使用的是纯SQL (与上面的结果相同)
library(sqldf)
ra$hits <-
sqldf('
select coalesce(sum(events), 0) as hits
from ra
left join ev
on ev.time > ra.a and ev.time < ra.b
group by ra.a
, ra.b
')[[1]]
发布于 2019-02-22 03:43:02
我们可以在data.table
中使用非等联接
library(data.table)
setDT(ev)[ra, .(hits = .N), on = .(time > a, time < b), by = .EACHI]
发布于 2019-02-22 03:41:52
可以这样做:
library(tidyverse)
crossing(ra, ev) %>%
group_by(a, b) %>%
summarise(hits = sum(between(time, a, b)))
输出:
# A tibble: 4 x 3
# Groups: a [4]
a b hits
<dbl> <dbl> <int>
1 0 250 2
2 250 500 1
3 500 750 2
4 750 900 0
https://stackoverflow.com/questions/54814910
复制相似问题