如何使用参数组合将 mapply 与不等长度的输入集一起使用?
How to use mapply with sets of inputs of unequal lengths, using combinations of arguments?
我正在尝试找到一种使用自定义函数 运行 进行多次模拟的方法。
每个模拟都使用不同的输入值,这些输入值基于现实生活中的测量结果。
假设此函数预测大田作物的产量。
predict <- function(input1, input2, input3){
output = input1 + input2 + input3
return(output)
}
我知道如何在参数列表上使用 mapply 到 运行 这个函数,但我找不到如何使用不同的输入组合(不等长列表).
为了说明,我有一个数据框(带有虚拟数字),每一行对应一个农场,每一列对应一个输入参数(除了第一个,这是农场代码)。
df <- data.frame("Farm" = 1:3, "input1" = c(10, 20 , 30), "input2" = c(100, 200, 300))
df
现在,正如您所注意到的,我在此数据框中没有第三个参数“input3”。
对于这个特定的论点,我有 1000 个不同的可能值。
all_possible_input3 <- seq(1:1000) # dummy values
我想 运行 观察到的农场参数和 1000 个不同可能值之间的每个组合的预测函数。
为了展示第一个组合的几个例子,每个人看起来像这样:
# For Farm 1:
Farm1_run1 <- predict(input1 = 10, input2 = 100, input3 = 1)
Farm1_run2 <- predict(input1 = 10, input2 = 100, input3 = 2)
Farm1_run3 <- predict(input1 = 10, input2 = 100, input3 = 3)
# ... and goes on to use the 1000 values for the third argument.
# For Farm 2:
Farm2_run1 <- predict(input1 = 20, input2 = 200, input3 = 1)
Farm2_run2 <- predict(input1 = 20, input2 = 200, input3 = 2)
Farm2_run3 <- predict(input1 = 20, input2 = 200, input3 = 3)
# ... and goes on to use the 1000 values for the third argument.
# For Farm 3:
Farm3_run1 <- predict(input1 = 30, input2 = 300, input3 = 1)
Farm3_run2 <- predict(input1 = 30, input2 = 300, input3 = 2)
Farm3_run3 <- predict(input1 = 30, input2 = 300, input3 = 3)
# ... and goes on to use the 1000 values for the third argument.
总共应该产生 3000 运行s,对应于 3 个农场和 1000 个可能输入之间的所有组合3。
我知道如何使用 mapply 在多个参数列表上循环一个函数,但如何处理长度不等的列表?
我想在第一个函数上叠加另一个 apply 函数,但我还没有找到解决方案。
也许首先拆分数据帧,然后将每一行组合到每个可能的 input3,然后将函数应用于每一行输入?
我希望我的例子足够清楚......
你能帮忙吗?
考虑第二次申请,您走在了正确的轨道上。你可以例如将你的 mapply
嵌套在 lapply
中,循环遍历你的 all_possible_input3
:
predict <- function(input1, input2, input3){
output = input1 + input2 + input3
return(output)
}
df <- data.frame("Farm" = 1:3, "input1" = c(10, 20 , 30), "input2" = c(100, 200, 300))
df
#> Farm input1 input2
#> 1 1 10 100
#> 2 2 20 200
#> 3 3 30 300
all_possible_input3 <- 1:10
farm_runs <- lapply(all_possible_input3, function(input3) {
mapply(predict, input1 = df$input1, input2 = df$input2, input3 = input3)
})
farm_runs
#> [[1]]
#> [1] 111 221 331
#>
#> [[2]]
#> [1] 112 222 332
#>
#> [[3]]
#> [1] 113 223 333
#>
#> [[4]]
#> [1] 114 224 334
#>
#> [[5]]
#> [1] 115 225 335
#>
#> [[6]]
#> [1] 116 226 336
#>
#> [[7]]
#> [1] 117 227 337
#>
#> [[8]]
#> [1] 118 228 338
#>
#> [[9]]
#> [1] 119 229 339
#>
#> [[10]]
#> [1] 120 230 340
有一种简洁的方法可以使用 outer
来做到这一点,它在其参数上交叉应用 FUN
。只需 Vectorize
函数调用的框架并将其放入 outer
中,如下所示:
FUN <- Vectorize(function(i, j) with(df, my_pred(input1[i], input2[i], a.input3[j])))
res1 <- outer(1:nrow(df), seq(a.input3), FUN)
res1
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 111 112 113 114 115 116 117 118 119 120
# [2,] 221 222 223 224 225 226 227 228 229 230
# [3,] 331 332 333 334 335 336 337 338 339 340
数据:
my_pred <- function(input1, input2, input3) { ## renamed because `predict` is actually used
output <- input1 + input2 + input3
return(output)
}
df <- structure(list(Farm = 1:3, input1 = c(10, 20, 30), input2 = c(100,
200, 300)), class = "data.frame", row.names = c(NA, -3L))
a.input3 <- seq(1:10) ## shortened for example
我正在尝试找到一种使用自定义函数 运行 进行多次模拟的方法。 每个模拟都使用不同的输入值,这些输入值基于现实生活中的测量结果。 假设此函数预测大田作物的产量。
predict <- function(input1, input2, input3){
output = input1 + input2 + input3
return(output)
}
我知道如何在参数列表上使用 mapply 到 运行 这个函数,但我找不到如何使用不同的输入组合(不等长列表). 为了说明,我有一个数据框(带有虚拟数字),每一行对应一个农场,每一列对应一个输入参数(除了第一个,这是农场代码)。
df <- data.frame("Farm" = 1:3, "input1" = c(10, 20 , 30), "input2" = c(100, 200, 300))
df
现在,正如您所注意到的,我在此数据框中没有第三个参数“input3”。 对于这个特定的论点,我有 1000 个不同的可能值。
all_possible_input3 <- seq(1:1000) # dummy values
我想 运行 观察到的农场参数和 1000 个不同可能值之间的每个组合的预测函数。 为了展示第一个组合的几个例子,每个人看起来像这样:
# For Farm 1:
Farm1_run1 <- predict(input1 = 10, input2 = 100, input3 = 1)
Farm1_run2 <- predict(input1 = 10, input2 = 100, input3 = 2)
Farm1_run3 <- predict(input1 = 10, input2 = 100, input3 = 3)
# ... and goes on to use the 1000 values for the third argument.
# For Farm 2:
Farm2_run1 <- predict(input1 = 20, input2 = 200, input3 = 1)
Farm2_run2 <- predict(input1 = 20, input2 = 200, input3 = 2)
Farm2_run3 <- predict(input1 = 20, input2 = 200, input3 = 3)
# ... and goes on to use the 1000 values for the third argument.
# For Farm 3:
Farm3_run1 <- predict(input1 = 30, input2 = 300, input3 = 1)
Farm3_run2 <- predict(input1 = 30, input2 = 300, input3 = 2)
Farm3_run3 <- predict(input1 = 30, input2 = 300, input3 = 3)
# ... and goes on to use the 1000 values for the third argument.
总共应该产生 3000 运行s,对应于 3 个农场和 1000 个可能输入之间的所有组合3。
我知道如何使用 mapply 在多个参数列表上循环一个函数,但如何处理长度不等的列表? 我想在第一个函数上叠加另一个 apply 函数,但我还没有找到解决方案。 也许首先拆分数据帧,然后将每一行组合到每个可能的 input3,然后将函数应用于每一行输入? 我希望我的例子足够清楚...... 你能帮忙吗?
考虑第二次申请,您走在了正确的轨道上。你可以例如将你的 mapply
嵌套在 lapply
中,循环遍历你的 all_possible_input3
:
predict <- function(input1, input2, input3){
output = input1 + input2 + input3
return(output)
}
df <- data.frame("Farm" = 1:3, "input1" = c(10, 20 , 30), "input2" = c(100, 200, 300))
df
#> Farm input1 input2
#> 1 1 10 100
#> 2 2 20 200
#> 3 3 30 300
all_possible_input3 <- 1:10
farm_runs <- lapply(all_possible_input3, function(input3) {
mapply(predict, input1 = df$input1, input2 = df$input2, input3 = input3)
})
farm_runs
#> [[1]]
#> [1] 111 221 331
#>
#> [[2]]
#> [1] 112 222 332
#>
#> [[3]]
#> [1] 113 223 333
#>
#> [[4]]
#> [1] 114 224 334
#>
#> [[5]]
#> [1] 115 225 335
#>
#> [[6]]
#> [1] 116 226 336
#>
#> [[7]]
#> [1] 117 227 337
#>
#> [[8]]
#> [1] 118 228 338
#>
#> [[9]]
#> [1] 119 229 339
#>
#> [[10]]
#> [1] 120 230 340
有一种简洁的方法可以使用 outer
来做到这一点,它在其参数上交叉应用 FUN
。只需 Vectorize
函数调用的框架并将其放入 outer
中,如下所示:
FUN <- Vectorize(function(i, j) with(df, my_pred(input1[i], input2[i], a.input3[j])))
res1 <- outer(1:nrow(df), seq(a.input3), FUN)
res1
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 111 112 113 114 115 116 117 118 119 120
# [2,] 221 222 223 224 225 226 227 228 229 230
# [3,] 331 332 333 334 335 336 337 338 339 340
数据:
my_pred <- function(input1, input2, input3) { ## renamed because `predict` is actually used
output <- input1 + input2 + input3
return(output)
}
df <- structure(list(Farm = 1:3, input1 = c(10, 20, 30), input2 = c(100,
200, 300)), class = "data.frame", row.names = c(NA, -3L))
a.input3 <- seq(1:10) ## shortened for example