【问题标题】:Using summarize (or equivalent?) to create a column of functions in an R dataframe使用汇总(或等效?)在 R 数据框中创建一列函数
【发布时间】:2019-05-17 23:59:06
【问题描述】:

我正在处理一些电力数据,这些电力数据对于每一小时、每一天和资产都有一个阶跃函数,该函数指定资产以不断上涨的价格提供电力。我想做的是将这些数据折叠成一个数据框、小标题等,带有日期、时间、资产和特定于行的步进函数。稍后我将使用该步进函数来填充其他一些列。

这是我想做的一个快速可重复的例子。

library(dplyr)
df_test<-data.frame(rep(1:25, times=1, each=4))
names(df_test)[1]<-"asset"
df_test$block<-rep(1:4, times=25)
df_test$from<-rep(seq(0,150,50), times=25)
df_test$to<-df_test$from+50
df_test$index<-runif(100)*100

df_test<-df_test %>% group_by(asset) %>% mutate(price=cumsum(index))

这基本上是我每天每小时的一个示例,除了在我的情况下,区块的数量是不同的(一些公司出价一个区块,其他公司出价高达 7 个区块,但这很可能对这里的问题不重要)。

现在,我想做的是,对于每个资产,使用 from、to 和 price 块并将其按资产存储在数据框中(同样,在我的扩展案例中,它将按日期、小时和资产)。

例如,使用第一组我可以这样做

generate_func<-function(x,y){
  stepfun(x, y, f = as.numeric(0), ties = "ordered",right = FALSE)
}

eg_func<-generate_func(df_test$from[2:4],df_test$price[1:4])

函数 eg_func 让我可以找到资产 1 在任何值 x 处的隐含价格。

eg_func(500)
[1] 43.10305

我想做的是按资产对数据进行分组,然后将每个资产的 eg_func 版本存储在数据框的第二列或等效项中。

基本上,我想做的是:

df_sum<-df_test %>% group_by(asset) %>% summarize(
  step_func=generate_func(from[-1],price)
) 

但我明白了:

Error: Column `step_func` is of unsupported type function

更新:

@akrun 让我更进一步。所以,如果我将函数包装在一个列表中,我可以做我想做的事……至少第一步:

df_func<-df_test %>%
  group_by(asset) %>% 
  summarize(step_func=list(generate_func(from[-1],price)))

所以现在我有一个数据框,每个资产都有一个阶梯函数。现在,我的下一个任务是能够评估该函数以创建一个新列,以特定值评估阶跃函数。因此,例如,我可以以 50 的值评估第一个资产的出价:

df_func[1,2][[1]][[1]](50)
[1] 49.60776

我希望能够在 mutate 命令中执行此操作,因此类似于:

df_func <-df_func %>% mutate(bid_50=step_func[[2]](50))

但这会将第二步功能应用于每个人。如何使用评估为 50 的每个资产的阶跃函数填充 bid_50 列?

使用解决方案再次更新#2 @akrun:

df_func <-df_func %>% mutate(bid_50=map_dbl(step_func, ~ .x(50)))

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    最好将其包装在list 中,因为eg_func 是一个函数,然后使用map 提取list 元素,将函数应用于传递的参数以创建新列'bid_50'

    library(tidyverse)
    df_test %>%
      group_by(asset) %>% 
      summarize(step_func=list(generate_func(from[-1],price))) %>%
      mutate(bid_50 = map_dbl(step_func, ~ .x(50)))
    

    【讨论】:

    • 是的,这正是我想要做的。谢谢你。如果可以的话,还有一个额外的后续问题。以后如何调用该函数。因此,例如,如果我想调用 df_func% group_by(asset) %>% summarise(step_func=list(generate_func(from[-1],price))) 然后 df_func % mutate(bid_50=step_func[[2]](50)) 我需要除 [[2]] 之外的其他东西,才能将每个资产的功能评估为 50。
    • @AndrewLeach 因为它存储在list 中,我们可以使用map 循环通过listmap_dbl(df_func$step_func, ~ .x(50))
    • 再次感谢。请在编辑后的帖子中查看上面关于使用 mutate 执行此操作的快速问题。
    • 非常感谢。这就是你今天为我节省的时间。
    猜你喜欢
    • 2017-12-31
    • 2021-11-24
    • 1970-01-01
    • 2022-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 2021-09-01
    相关资源
    最近更新 更多