2017-07-10 5 views
1

ベクトルと行をほとんど使わないで単純な演算を行う必要があります。R:異なる接尾辞を持つベクトルに演算を適用する

は、Iのようなデータベースを持っていると仮定:

observation  outcome_1_a outcome_2_a outcome_1_b outcome_2_b choice_a choice_b 
1    41   34   56   19   1  1 
2    32   78   43   6   2  1 
3    39   19   18   55   1  2 
各観察、outcome_1について

二つの可能な結果がoutcome_2あるiは、Bは=と、選択は、選択された結果とプレフィックス_iであります状況が繰り返される回数を示します。

私は、したがって、(a、b)は各状況のための最高の結果を格納した変数作成する場合:私は、各状況で選択した値を格納する変数を作成したい場合は、同様に

max.a <- pmax(data$outcome_1_a, data$outcome_2_a) 
max.b <- pmax(data$outcome_1_b, data$outcome_2_b) 

は、私が行うことができます。

choice.a <- ifelse(data$choice_a == "1", data$outcome_1_a, data$outcome_1_b) 
choice.b <- ifelse(data$choice_b == "1", data$outcome_2_a, data$outcome_2_b) 

を最後に、私は状況の行 AとBとで平均値を計算したい場合は、私ができますdo:

library(data.table) 
setDT(data) 
data[, .(Mean = rowMeans(.SD)), by = observation, .SDcols = c("outcome_1_a","outcome_2_a", "outcome_1_b", "outcome_2_b")] 

これらのすべてはうまくいきます。しかし、私はそのような操作がより効率的な方法で実行できるかどうか疑問に思っていました。

この例では、の状況はですが、将来的には15個以上の異なる状況(a、b、c、d、...、 )、そのような操作を書くことは面倒かもしれません。

変数の異なる接頭辞や接尾辞に基づいて、このようなプロセスを自動化する方法はありますか?

ありがとうございました

答えて

1

正規表現を使用して列を選択できます。たとえば、max.aの値を取得します。

library(data.table) 

setDT(data) 
data[, do.call(pmax, .SD), .SDcols = names(data) %like% "\\d+_a$"] 

[1] 41 78 39 

また、data.table以外の正規表現を使用して列を選択することもできます。これについては多くの方法があります。

最後のコマンドと同様のアプリケーションです。あなたは電子など、B、C、Dの間で選択する方法を

choice.aについては
data[, 
    .(Mean = rowMeans(.SD)), 
    by = observation, 
    .SDcols = names(data) %like% "^outcome"] 
    observation Mean 
1:   1 37.50 
2:   2 39.75 
3:   3 32.75 

、?例えば

+0

ありがとうございます。あなたのコードは、 'RowMeans'の場合にうまく機能します。しかし、もし私が何か働いていれば私を許してください。列ごとの最大値の場合、プロセスを自動化しません。つまり、 'data [、do.call(pmax、.SD)、.SDcols = names(data)% % "\\ d + _a $"] 'のように' pmax(data $ outcome_1_a、data $ outcome_2_a) 'と同じ出力を返します。私はまだ 'SDcols'引数で手動で手紙を変更する必要があります –

1

outcome_1_a outcome_2_a outcome_1_b outcome_2_b outcome_1_c outcome_2_c outcome_1_d outcome_2_d outcome_1_e outcome_2_e choice_a choice_b choice_c choice_d choice_e 
     <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1   12   85   32   28   91   42   32   96   27   29  2  1  1  1  1 
2   17   22   84   53   11   69   16   66   11   41  1  2  2  1  1 
3   92   98   76   83   18   27   21   51   92   41  1  1  1  1  2 
4   63   49   61   64   100   28   43   51   22   94  1  2  1  1  1 

あなたがループを通過するのに役立ちますインデックス変数を定義します。

seqmax <- seq(1, 10, by = 2) 

seqmax1 3 5 7 9です。その理由は、5文字の"a" "b" "c" "d" "e"があるからです。したがって、このシーケンスはループをパターン化するのに役立ちます。これは、最大文字数のために自動化することができます。choice_aの前に最後の列の列インデックスを探します。その後、seq(1, grep(names(data), pattern = "choice_a") - 1, by = 2)を実行できます。by = 2引数は、文字数で列数を調整できます。

私はdataに新しい列を付けるのにlapply<<-を使用します。

lapply(c(1:5), function(x){ 

    data[, paste0("max.", letters[x])] <<- apply(data[, c(seqmax[x], seqmax[x] + 1)], 1, max) 

    data[, paste0("choice.", letters[x])] <<- ifelse(
    data[, grep(names(data), pattern = paste0("choice_", letters[x]), value = T)] == 1, 
    data[, seqmax[x]], data[, seqmax[x] + 1]) 

    data[, paste0("mean.", letters[x])] <<- rowMeans(
    data[, grep(names(data), pattern = paste0("outcome_\\d+_", letters[x]), value = T)]) 

}) 
関連する問題