微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用多参数函数生成变量参数值的排列

如何解决使用多参数函数生成变量参数值的排列

我正在使用具有3个组件(alpha beta和switchpoint)的函数。我需要调整这3个组件以创建这些参数的多个排列。这是一些代码,用于演示一个简单的示例,其中已为参数指定了特定的值

a <- 2 # alpha
b <- 2 # beta 
sp <- 50 # Switch Point 

set.seed(123)
df <- data.frame(X1 = seq(0,200,by=10),X2 = sample(0:200,21 )) 

这是上述参数值的公式

    attach(df)

df$X1_a2_b2_sp50 <- ((X1/(((-(-(sp^a)*a-(sp^a)))/(a*b-b))^(1/a)))^a)/(((X1/(((-(-(sp^a)*a-(sp^a)))/(a*b-b))^(1/a)))^a)+ b)

> df
    X1  X2 X1_a2_b2_sp50
1    0 158    0.00000000
2   10 178    0.01315789
3   20  13    0.05063291
4   30 194    0.10714286
5   40 169    0.17582418
6   50  49    0.25000000
7   60 117    0.32432432
8   70  42    0.39516129
9   80 198    0.46043165
.
etc

从新变量可以看到,它的名称以X1开头表示原始变量名称,然后它的a2表示alpha级别,b = 2和sp = 50时也一样。我需要创建多个转换来更改值a,b,sp。以下是我需要为每个参数更改的值的列表。我还需要对多个变量执行此操作,对X2也是如此。

a_list <- c(2,3,4)
b_list <- c( 2,5) 
sp_list <- c(50,100,150,200)
var_list <- c("X1","X2")

X1的结果将创建24个变量= 3(a)x 2(b)x 4(sp)

# For X1,there should be these variables

df$X1_a2_b2_sp50
df$X1_a2_b2_sp100
df$X1_a2_b2_sp150
df$X1_a2_b2_sp200
df$X1_a2_b5_sp50
df$X1_a2_b5_sp100
df$X1_a2_b5_sp150
df$X1_a2_b5_sp200
df$X1_a3_b2_sp50
df$X1_a3_b2_sp100
df$X1_a3_b2_sp150
df$X1_a3_b2_sp200
df$X1_a3_b5_sp50
df$X1_a3_b5_sp100
df$X1_a3_b5_sp150
df$X1_a3_b5_sp200
df$X1_a4_b2_sp50
df$X1_a4_b2_sp100
df$X1_a4_b2_sp150
df$X1_a4_b2_sp200
df$X1_a4_b5_sp50
df$X1_a4_b5_sp100
df$X1_a4_b5_sp150
df$X1_a4_b5_sp200

然后对X2相同。我要解决方法是使用for循环(每个参数)并使用Assign创建变量名称。我只是想知道是否有更简单的方法可以简化此过程?可以在R中以其他方式完成此操作吗?任何建议将不胜感激。如果有任何推荐的软件包或方法,我可以调查一下。预先非常感谢。

解决方法

您可以做的是:。

  1. 首先使用tidyr::expand_grid用a_list,b_list和sp_list的所有可能组合构建一个数据框
  2. 从此df构造参数化函数调用的命名列表
  3. 已使dplyr使用mutate(across())在您选择的变量上运行所有这些功能

我希望这能使您到达想要的地方:)

library(tidyr)
library(dplyr)

a_list <- c(2,3,4)
b_list <- c( 2,5)
sp_list <- c(50,100,150,200)
var_list <- c("X1","X2")

param_df <-  expand_grid(
    a = a_list,b = b_list,sp = sp_list
  ) %>%
  mutate(
    colname = paste0("a",a,"_b",b,"_sp",sp)
  )

my_fun <- function(a,sp,...) {
  function(vec){
    ((vec/(((-(-(sp^a)*a-(sp^a)))/(a*b-b))^(1/a)))^a)/(((vec/(((-(-(sp^a)*a-(sp^a)))/(a*b-b))^(1/a)))^a)+ b)
  }
}

funs_ls <- param_df %>%
  pmap(my_fun) %>%
  setNames(param_df$colname)

result <- df %>%
  mutate(
    across(
      .cols = all_of(var_list),funs_ls
    )
  )
,

@alex,这里只是分享我的做法。我也学习了如何创建函数以使其变得更容易。我对dplr这样的R没有很好的了解,所以它是一种更简单的方法。

set.seed(123)
df <- data.frame(X1 = seq(0,200,by=10),X2 = sample(0:200,21 )) 

a_list <- c(2,"X2")

attach(df)

func_dr <- function(x,sp) 
{  ((x/(((-(-(sp^a)*a-(sp^a)))/(a*b-b))^(1/a)))^a)/(((x/(((-(-(sp^a)*a-(sp^a)))/(a*b-b))^(1/a)))^a)+ b) }

container <- numeric()

for (i in 1:length(var_list)) {
  for (j in 1:length(a_list)) {
    for (k in 1:length(b_list)) {
      for (l in 1:length(sp_list)) {
    
        result <- func_dr(eval(parse(text = var_list[i])),a_list[j],b_list[k],sp_list[l]  )
        container <- cbind(container,result)
        colnames(container)[ncol(container)] <- paste(var_list[i],paste("a",sep = ""),paste("b",paste("sp",sp_list[l],sep = "_")
      }
    }
  }
}

这可能不是用R编写的好方法,但我仍在学习。谢谢

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。