首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >R:特征提取的循环函数编码有问题吗?

R:特征提取的循环函数编码有问题吗?
EN

Stack Overflow用户
提问于 2018-12-17 00:06:37
回答 3查看 67关注 0票数 2

我有两个向量:

代码语言:javascript
复制
 EventDate <- c("2018-10-31", "2018-11-16", "2018-12-02")
 ThirtyDaysPriorEvent <- c("2018-10-01", "2018-10-17", "2018-11-02")

我需要帮助为以下工作流程编写循环函数:

  1. 循环遍历向量以标识相同索引位置中的日期,并将它们存储在变量中。例如,第一对日期是EventDate1 & ThirtyDaysPriorEvent1。对于示例数据,值为"2018-10-31“,并在dplyr的"2018-10-01".
  2. Use函数中将变量作为日期参数进行过滤。查询数据库,查找每个事件日期前30天发生的所有活动。使用第3步中的计算值将结果存储在名为Activities30dys.
  3. Compute dataframe.
  4. Create of columns in Activities30dys的数据帧中,并在事件数据帧中创建一个新列。

这是我想要实现的结果:

事件数据框中名为"d“的新列,该列来自活动数据框中列"x”中的聚合值。

代码语言:javascript
复制
      date  a    b     c     d
2018-10-31 42 60.5 152.4 16.63
2018-11-16 54 54.1 151.6 16.63
2018-12-02 63 74.2 153.5 19.95

然而,这就是我所得到的:

代码语言:javascript
复制
 library(dplyr)

 # identifies dates in the same index position for each vector & stores results in variables
 e <- EventDate[1]
 e30 <- ThirtyDaysPriorEvent[1]

 # uses variables to filter Activities dataframe
 Activities30Dys <- Activities %>%
   filter(date > e30 & date < e) 

 # computes sum of x activity done 30 days prior to event date
 sum(Activities30Dys$x, na.rm = TRUE)

 # adds new column (d) to Events dataframe
 Events %>%
   mutate()

以下是我的可重现数据:

代码语言:javascript
复制
     Events <- structure(list(date = c("2018-10-31", "2018-11-16", "2018-12-02"
), a = c(42L, 54L, 63L), b = c(60.5, 54.1, 74.2), c = c(152.4, 
151.6, 153.5)), .Names = c("date", "a", "b", "c"), row.names = 
c(NA, 3L), class = "data.frame")

     Activities <- structure(list(date = c("2018-09-18", "2018-09-19", "2018-10-21", 
"2018-10-21", "2018-10-24", "2018-10-26", "2018-10-27", "2018-11-18", 
"2018-11-19", "2018-11-21", "2018-11-24", "2018-11-26", "2018-11-27", 
"2018-12-05"), x = c(3.43, 3.16, 3.2, 3.27, 3.74, 3.2, 3.22, 
3.43, 3.16, 3.2, 3.74, 3.2, 3.22, 3.02), y = c(132L, 122L, 120L, 
130L, 127L, 128L, 127L, 132L, 122L, 120L, 127L, 128L, 127L, 121L
)), .Names = c("date", "x", "y"), row.names = c(NA, 14L), class = "data.frame")

我如何才能最好地使用R来实现我的目标?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-12-17 00:55:30

这里有一种方法可以做到。在众多案例中。

代码语言:javascript
复制
extend_df <- function(events, priors, data) {

require(dplyr)

monthly <- list()
for (i in seq_along(events)) {

  to <- events[i]
  from <- priors[i]

  monthly[[i]] <- data %>%
    filter(date > from & date < to) %>% 
    summarise(n = sum(x)) %>% 
    pull(n)


  }
return(monthly)
}

Events %>% mutate(d = extend_df(EventDate, ThirtyDaysPriorEvent, Activities))

        date  a    b     c     d
1 2018-10-31 42 60.5 152.4 16.63
2 2018-11-16 54 54.1 151.6 16.63
3 2018-12-02 63 74.2 153.5 19.95
票数 1
EN

Stack Overflow用户

发布于 2018-12-17 01:17:04

我有几种方法来处理它,这取决于它如何适应您的工作流程。purrr::map系列函数使得在这些向量上进行映射而不是循环变得很容易。在这种情况下,map2将同时映射到一对向量上。

我要注意的第一件事是,由于您使用的是dates,因此最好将其视为dates,并将其转换为Date类。

另一件事是,当你过滤的时候,不清楚你是想要你的端点是包含的还是排他的。我使用dplyr::between作为速记,但这将包括端点。我会让你根据需要进行调整。

一种方法是使用map2_dfr在两个日期矢量上进行映射,以返回数据框,过滤Activities,按开始日期分组,然后汇总。这将得到一个数据框,然后可以使用Events连接它,前提是您已经将它的日期转换为实际的Date

代码语言:javascript
复制
library(dplyr)
library(purrr)

sums_df <- map2_dfr(as.Date(EventDate), as.Date(ThirtyDaysPriorEvent), function(e, e30) {
  activities30dys <- Activities %>%
    mutate(date = as.Date(date)) %>%
    filter(between(date, e30, e)) %>%
    group_by(date = e) %>%
    summarise(d = sum(x, na.rm = T))

  activities30dys
})

Events %>%
  mutate(date = as.Date(date)) %>%
  left_join(sums_df, by = "date")
#>         date  a    b     c     d
#> 1 2018-10-31 42 60.5 152.4 16.63
#> 2 2018-11-16 54 54.1 151.6 16.63
#> 3 2018-12-02 63 74.2 153.5 19.95

另一种选择是执行类似的map2,但使用map2_dbl返回单个数字向量。然后,您可以使用mutate将其作为列添加到Events

代码语言:javascript
复制
sums_dbl <- map2_dbl(as.Date(EventDate), as.Date(ThirtyDaysPriorEvent), function(e, e30) {
  activities30dys <- Activities %>%
    mutate(date = as.Date(date)) %>%
    filter(between(date, e30, e))

  sum(activities30dys$x, na.rm = T)
})

Events %>%
  mutate(d = sums_dbl)
#>         date  a    b     c     d
#> 1 2018-10-31 42 60.5 152.4 16.63
#> 2 2018-11-16 54 54.1 151.6 16.63
#> 3 2018-12-02 63 74.2 153.5 19.95

最后要注意的是,您可以只计算之前的日期,而不是存储事件日期和30天前的日期的向量。如果您已转换为Date,则e - 30会向您提供30天前的日期,您可以像这样构建您的工作流:

代码语言:javascript
复制
map(as.Date(EventDate), function(e) {
  e30 <- e - 30
  # ...
})
票数 2
EN

Stack Overflow用户

发布于 2018-12-17 00:51:44

我确信我们可以为此做一个完整的dplyr解决方案,但不能不对数据进行显著的重塑。

因此,我提供了一个简单的for循环解决方案,主要是重用您编写的代码。这些小的修改是为了代码的易读性:

代码语言:javascript
复制
#-- Initialize d
Events$d <- NA

#-- Run loop
for (i in 1:nrow(Events)) {
  e <- Events$date[i]
  e30 <- e - 30
  Events$d[i] <- Activities %>%
    filter(between(date, e30, e)) %>%
    summarize(x = sum(x, na.rm = TRUE)) %>%
    pull()
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53803976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档