r - 複数のパラメーター関数を使用して変数を生成します (パラメーター値の順列を使用)

okwaves2024-01-25  9

アルファ ベータとスイッチポイントの 3 つのコンポーネントを持つ関数を使用しています。これら 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 があり、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で他の方法で行うことはできますか?アドバイスをいただければ幸いです。推奨するパッケージやメソッドがある場合は、それを検討できます。よろしくお願いいたします。



------------------------

できることは次のとおりです。

まず、tidyr::expand_grid を使用して、a_list、b_list、sp_list のすべての可能な組み合わせでデータ フレームを構築します。 構築するこの DF からのパラメータ化された関数呼び出しの名前付きリスト 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, b, 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
    )
  )

1

ありがとう、それは素晴らしいですね。最終的にはループでなんとかできましたが、上記の param_df の使い方がとても気に入りました。あなたのアプローチの柔軟性がわかります。改めて感謝申し上げます。

– ショーン

2020 年 9 月 5 日 1:23



------------------------

@alex、ここでは私が行った方法を共有します。それを少し簡単にするために関数を作成する方法も学びました。私は dplr などの R についてあまり理解していないので、より簡単な方法で実行しました。

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

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

attach(df)

func_dr <- function(x, a, b, 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", a_list[j], sep = ""), 
                                                      paste("b", b_list[k], sep = ""), 
                                                      paste("sp", sp_list[l], sep = ""), 
                                                      sep = "_")
      }
    }
  }
}

これはおそらく R で記述する良い方法ではありませんが、私はまだ学習中です。ありがとう

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。