gpt4 book ai didi

r - dplyr mutate 调用另一个数据帧

转载 作者:行者123 更新时间:2023-12-04 11:49:48 25 4
gpt4 key购买 nike

我想通过应用调用另一个数据帧的函数来改变数据帧。我可以通过几种不同的方式实现这一点,但想知道如何“正确”做到这一点。

这是我正在尝试做的一个例子。我有一个带有一些开始时间的数据框,还有一个带有一些定时观察的数据框。我想返回一个包含开始时间的数据帧,以及开始时间后某个窗口内发生的观察次数。例如

set.seed(1337)
df1 <- data.frame(id=LETTERS[1:3], start_time=1:3*10)
df2 <- data.frame(time=runif(100)*100)
lapply(df1$start_time, function(s) sum(df2$time>s & df2$time<(s+15)))

到目前为止,我对 dplyr 的最佳使用如下(但这会丢失身份变量):
df1 %>% 
rowwise() %>%
do(count = filter(df2, time>.$start_time, time < (.$start_time + 15))) %>%
mutate(n=nrow(count))

输出:
Source: local data frame [3 x 2]
Groups: <by row>

# A tibble: 3 × 2
count n
<list> <int>
1 <data.frame [17 × 1]> 17
2 <data.frame [18 × 1]> 18
3 <data.frame [10 × 1]> 10

我期待能够做到这一点:
df1 <- data.frame(id=LETTERS[1:3], start_time=1:3*10)
df2 <- data.frame(time=runif(100)*100)
df1 %>%
group_by(id) %>%
mutate(count = nrow(filter(df2, time>start_time, time<(start_time+15))))

但这会返回错误:
Error: comparison (6) is possible only for atomic and list types

dplyr 这样做的方法是什么?

最佳答案

这是 data.table 的一种选择我们可以在哪里使用 non-equi加入

library(data.table)#1.9.7+
setDT(df1)[, start_timeNew := start_time + 15]
setDT(df2)[df1, .(id, .N), on = .(time > start_time, time < start_timeNew),
by = .EACHI][, c('id', 'N'), with = FALSE]
# id N
#1: A 17
#2: B 18
#3: C 10

这与 OP 的 base R 中的计数相同方法
sapply(df1$start_time, function(s) sum(df2$time>s & df2$time<(s+15)))
#[1] 17 18 10

如果我们需要'id'变量也作为 dplyr的输出,我们可以修改OP的代码
df1 %>%
rowwise() %>%
do(data.frame(., count = filter(df2, time>.$start_time,
time < (.$start_time + 15)))) %>%
group_by(id) %>%
summarise(n = n())
# id n
# <fctr> <int>
#1 A 17
#2 B 18
#3 C 10

或者另一个选项是 map来自 purrrdplyr
library(purrr)
df1 %>%
split(.$id) %>%
map_df(~mutate(., N = sum(df2$time >start_time & df2$time < start_time + 15))) %>%
select(-start_time)
# id N
#1 A 17
#2 B 18
#3 C 10

关于r - dplyr mutate 调用另一个数据帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39689205/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com