我在SO上广泛搜索了一下,但没有找到和我一模一样的问题的答案。
我试图用一个函数来生成一些时间序列条目,这个函数从多变量参数的 inputs
数据框。每个变量集 {x,y,z,...}
从 inputs
生成一个时间序列数据框架;其中的集合需要解列。
的 inputs
数据框本身是混合类型(字符和双数),所以我一直有问题。apply
函数,但我理解该函数在内部转换为矩阵对象,因此失败。mapply
似乎是理想的候选者(而过程 运行 但结果是无效的,因为时间序列生成函数本身是矢量化的,因为它生成的是正态分布)
我的下面的代码运行时却给出了错误的结果
library(dplyr)
library(truncnorm)
forecast_curve <- function(case_id,
wal,
wal_sd,
amt,
n_qrtr) {
result <-
tibble(case_id = case_id,
quarter = seq(1, n_qrtr, 1)
) %>%
mutate(
amt_qrtr = amt *
dtruncnorm(seq(1, n_qrtr, 1),a = 1,b = n_qrtr,mean = wal, sd = wal_sd)
)
return(result)
}
#Generate inputs
inputs <-
tibble(
case_id = letters[1:10],
wal = seq(5,14,1),
wal_sd = rep(4,10),
total_amt_FC = c(10,9,8,7,6,5,4,3,2,1),
n_qrtr = rep(12,10)
)
#outputs function
outputs <- function(){
tmp <-
mapply(
forecast_curve,
inputs$case_id,
inputs$wal,
inputs$wal_sd,
inputs$total_amt_FC,
inputs$n_qrtr
)
tmp <-
as.data.frame(apply(tmp, 1, unlist)) %>%
tibble() %>%
mutate(
quarter = as.numeric(quarter),
amt_qrtr = as.numeric(amt_qrtr)
) %>%
arrange(case_id,quarter)
return(tmp)
}
如果仔细观察 case_id == a
那么结果是这样的
print(outputs() %>% filter (case_id == 'a'), n= 30)
case_id quarter amt_qrtr
<fct> <dbl> <dbl>
1 a 1 80
2 a 2 65
3 a 3 52
4 a 4 39
5 a 5 89
6 a 6 94
7 a 7 95
8 a 8 96
9 a 9 95
10 a 10 94
11 a 11 89
12 a 12 80
然而,同样的参数的正确结果(它与第一行中的 inputs
)是
#Correct example output
forecast_curve('a',5,4,10,12)
case_id quarter amt_qrtr
<chr> <dbl> <dbl>
1 a 1 0.755
2 a 2 0.940
3 a 3 1.10
4 a 4 1.21
5 a 5 1.24
6 a 6 1.21
7 a 7 1.10
8 a 8 0.940
9 a 9 0.755
10 a 10 0.570
11 a 11 0.404
12 a 12 0.269
从SO的类似问题来看,解决的办法是用 do.call
但我不能让它与我的情况下,下面的工作。
非常感谢任何指导
你把问题弄得比它更难。 假设你有一个函数,如 forecast_curve
,你可以直接用 mapply
. 没有必要。outputs
功能。
在控制台窗口中,输入 ?mapply
来看看帮助 mapply
这样你就可以看到所需的参数。 mapply
将调用为 FUN
,传递给 FUN
中每个向量的第一个值。...
参数。 然后,它将再次调用该函数,使用 ...
参数。 以此类推。 如果你设置了 SIMPLIFY = F
,结果总是以列表形式返回。
因为 forecast_curve
返回一个tibble,当你 mapply
与 FUN = forecast_curve
,你将得到一个tibbles的列表。 因此,下面的代码将返回一个包含10个tibbles的列表,每一行都有一个tibbles。inputs
tibble。
listOfTibbles =
mapply(
forecast_curve,
inputs$case_id,
inputs$wal,
inputs$wal_sd,
inputs$total_amt_FC,
inputs$n_qrtr,
SIMPLIFY = F
)
如果您想将所有这些 tibbles 合并成一个 tibble,您需要使用 rbind
,不 unlist
. 你可以这样做。
singleTibble = rbind(listOfTibbles[[1]], listOfTibbles[[2]], listOfTibbles[[3]], listOfTibbles[[4]], listOfTibbles[[5]], listOfTibbles[[6]], listOfTibbles[[7]], listOfTibbles[[8]], listOfTibbles[[9]], listOfTibbles[[10]])
但是... do.call
提供了一个更简单的方法。 do.call
调用一个函数(在本例中。rbind
)使用列表中的值作为函数的参数。 因此,使用以下方法可以得到同样的结果。
singleTibble = do.call(rbind, listOfTibbles)