2017-05-17 22 views
1

私は、各行がスタディの参加者を表すデータフレーム(dat)を持っています。各参加者(「コード」)には、性別(「性別」)と年齢(「年齢」)、テスト結果を示す列(「v.1」など)を示す列があります。データフレームは、このようなものになります。テスト結果の各列に対して同じmapply関数を使用して複数の新しい変数を作成する

> dat 
    code sex age v.1 v.2 
1 A1 m 8 4 9 
2 B2 f 12 7 2 

を、私は8のデータフレーム(例えば「v.1.m.8」の外に対応するベクトルの値をルックアップする必要があります12歳の女性参加者の場合は「v.1.f.12」)、そのベクトルの値をデータフレームの新しい列(「v.1.t」)に挿入します。男性と女性の参加者と異なる年齢層の異なるベクトルがあります。ベクトルはこのような何かを見て:私にとって

v.1.m.8 <- c(4, 5, 2, 8, 2, ...) 
v.2.m.8 <- c(3, 2, 2, 1, 8, ...) 
v.1.m.12 <- c(...) 
v.2.m.12 <- c(...) 
v.1.f.8 <- c(...) 
v.2.f.8 <- c(...) 
v.1.f.12 <- c(...) 
v.2.f.12 <- c(...) 

を、ベクトル内の値を検索するための最も論理的に簡単な方法は、場合-statemenst forループnestesです。ソートまたは、このように:

for (i in nrow(dat)) { 
    if (dat[i, ]$age < 8 | dat[i, ]$age > 18) { 
     dat[i, ]$v.1.t <- NA 
     dat[i, ]$v.2.t <- NA 
    } else if (dat[i, ]$age < 12) { 
     if (dat[i, ]$dat.sex == "m") { 
      dat[i, ]$v.1.t <- v.1.m.8[dat[i, ]$v.1] 
      dat[i, ]$v.2.t <- v.2.m.8[dat[i, ]$v.2] 
     } else { 
      dat[i, ]$v.1.t <- v.1.f.8[dat[i, ]$v.1] 
      dat[i, ]$v.2.t <- v.2.f.8[dat[i, ]$v.2] 
     } 
    } else { 
     if (dat[i, ]$dat.sex == "m") { 
      dat[i, ]$v.1.t <- v.1.m.12[dat[i, ]$v.1] 
      dat[i, ]$v.2.t <- v.2.m.12[dat[i, ]$v.2] 
     } else { 
      dat[i, ]$v.1.t <- v.1.f.12[dat[i, ]$v.1] 
      dat[i, ]$v.2.t <- v.2.f.12[dat[i, ]$v.2] 
     } 
    } 
} 

ループを回避するために、私は(mapply使用する場合があります)この方法のようなもので:

dat$v.1.t <- mapply(
    function(a, b, c) { 
     if (a < 8 | a > 18) { 
      NA 
     } else if (a < 12) { 
      if (b == "m") { 
       v.1.m.8[c] 
      } else { 
       v.1.f.8[c] 
      } 
     } else { 
      if (b == "m") { 
       v.1.m.12[c] 
      } else { 
       v.1.f.12[c] 
      } 
     } 
    }, 
    dat$age, 
    dat$dat.sex, 
    dat$v.1 
) 

dat$v.2.t <- mapply(
    function(a, b, c) { 
     if (a < 8 | a > 18) { 
      NA 
     } else if (a < 12) { 
      if (b == "m") { 
       v.2.m.8[c] 
      } else { 
       v.2.f.8[c] 
      } 
     } else { 
      if (b == "m") { 
       v.2.m.12[c] 
      } else { 
       v.2.f.12[c] 
      } 
     } 
    }, 
    dat$age, 
    dat$dat.sex, 
    dat$v.2 
) 

この第二の解決策の問題は、私が繰り返さなければならないということです私が割り当てたい各変数の全コード。

もっと良い解決策はありますか?

実際のコードでは、11個の新しい列を作成するために44個のベクトルで11個の列を検索する必要があります。

私は

+0

外部ベクターとの比較はどのように行うべきですか?同様に、そのベクトルのどの値をデータセットの新しい変数に書き込む必要があるかを決定する方法は? 'テスト結果の列ごとに、データフレームの外の対応するベクトルの値を調べる必要があります(たとえば、8歳の男性参加者の場合は「v.1.m.8」、または「v.1.f.12」の場合) 12歳の女性参加者)、そのベクトルの値をデータフレームの新しい列( "v.1.t")に挿入します。これらの名前はベクトルで、データの値をベクトルを選択し、対応する値を選択しますか? @LeoP。 – LAP

+0

"v.1.m.8"はベクトルの1つの名前です。 dat $ v.1.tの値は、このベクトルのdat $ v.1の値の位置にある値です。例えば。 'dat $ v.1.t < - v.1.m.8 [dat $ v.1]'です。どのベクトルが選択されるかは、参加者の年齢および性別によって決まります。たとえば、ベクトル「v.1.m.8」には、12歳未満の男性参加者の値が含まれています。 –

答えて

0

によって分割を指摘し。

データ例(おかげ@Adam Quek):

dat <- data.frame(code = paste0(LETTERS[1:24], 1:24), sex=c("m", "f"), 
        age=c(8,12, 12, 8), v.1 = sample(1:10, 24, replace=T), 
        v.2 = sample(1:10, 24, replace=T)) 

ベクトル例:新しい変数v.1.tため

v.1.m.8 <- c(21:30) 
v.1.f.8 <- c(31:40) 
v.1.m.12 <- c(41:50) 
v.1.f.12 <- c(51:60) 

コード

次の例では、ただ一つの新しい変数のためであります:

dat$v.1.t <- with(dat, ifelse(!(age %in% c(8,12)), NA, 
          ifelse(age == 8 & sex == "m", v.1.m.8[v.1], 
           ifelse(age == 8 & sex == "f", v.1.f.8[v.1], 
             ifelse(age == 12 & sex == "m", v.1.m.12[v.1], 
               v.1.f.12[v.1]))))) 

年齢制限は、より多くのカテゴリを含み、可能なベクトルを分岐するように簡単に編集することができます。

出力:

code sex age v.1 v.2 v.1.t 
1 A1 m 8 10 1 30 
2 B2 f 12 6 5 56 
3 C3 m 12 10 3 50 
4 D4 f 8 7 10 37 
5 E5 m 8 5 4 25 
6 F6 f 12 6 9 56 
7 G7 m 12 2 9 42 
8 H8 f 8 2 3 32 
9 I9 m 8 4 1 24 
10 J10 f 12 7 4 57 
11 K11 m 12 7 4 47 
12 L12 f 8 9 10 39 
13 M13 m 8 9 2 29 
14 N14 f 12 5 8 55 
15 O15 m 12 1 10 41 
16 P16 f 8 8 4 38 
17 Q17 m 8 6 7 26 
18 R18 f 12 4 10 54 
19 S19 m 12 10 1 50 
20 T20 f 8 9 6 39 
21 U21 m 8 9 8 29 
22 V22 f 12 10 2 60 
23 W23 m 12 6 6 46 
24 X24 f 8 6 7 36 

次の2つの層(4つのベクトルそれぞれに11個のリストのリスト)をリストにベクトルを入れて、あなたの11個の変数のすべてのためのifelse()を書きたくない場合やあなたの変数とベクトルリストのリストの上のmapply()

編集:

私はmapply()と実装について考えて、私はシンプルなfor() -loopが簡単だと思います。

それを行う必要があり、以下の(二つの変数と4つのベクトルそれぞれ(M8、F8、M12、F12)を用いて実施例):

ベクター:ベクターの

v.1.m.8 <- c(21:30) 
v.1.f.8 <- c(31:40) 
v.1.m.12 <- c(41:50) 
v.1.f.12 <- c(51:60) 
v.2.m.8 <- c(61:70) 
v.2.f.8 <- c(71:80) 
v.2.m.12 <- c(81:90) 
v.2.f.12 <- c(91:100) 

リスト:

myvectors <- list("v.1" = list(v.1.m.8, v.1.f.8, v.1.m.12, v.1.f.12), 
        "v.2" = list(v.2.m.8, v.2.f.8, v.2.m.12, v.2.f.12)) 

for() -loop(リストの名前だけをループするため、ic("v.1", "v.2"))

です。
for(i in names(myvectors)){ 
    dat[, paste(i, "t", sep = ".")] <- with(dat, ifelse(!(age %in% c(8,12)), NA, 
       ifelse(age == 8 & sex == "m", myvectors[[i]][[1]][eval(parse(text = i))], 
       ifelse(age == 8 & sex == "f", myvectors[[i]][[2]][eval(parse(text = i))], 
        ifelse(age == 12 & sex == "m", myvectors[[i]][[3]][eval(parse(text = i))], 
        myvectors[[i]][[4]][eval(parse(text = i))]))))) 
} 

出力:これにより

code sex age v.1 v.2 v.1.t v.2.t 
1 A1 m 8 3 2 23 62 
2 B2 f 12 7 10 57 100 
3 C3 m 12 2 3 42 83 
4 D4 f 8 7 6 37 76 
5 E5 m 8 2 10 22 70 
6 F6 f 12 1 9 51 99 
7 G7 m 12 10 6 50 86 
8 H8 f 8 4 6 34 76 
9 I9 m 8 3 1 23 61 
10 J10 f 12 5 4 55 94 
11 K11 m 12 5 5 45 85 
12 L12 f 8 3 8 33 78 
13 M13 m 8 10 9 30 69 
14 N14 f 12 3 4 53 94 
15 O15 m 12 6 2 46 82 
16 P16 f 8 8 3 38 73 
17 Q17 m 8 9 5 29 65 
18 R18 f 12 5 6 55 96 
19 S19 m 12 6 4 46 84 
20 T20 f 8 2 9 32 79 
21 U21 m 8 5 1 25 61 
22 V22 f 12 2 1 52 91 
23 W23 m 12 3 10 43 90 
24 X24 f 8 2 9 32 79 

、あなたが準備する必要がある唯一のことは、最初のレベルで正しい名前のサブリストとベクトルのリストのリストである(そう"v.1""v.11"にして上に示したように"v.1"および"v.2"。サブリストの4つのベクトルの順序が常に同じであることを確認してください。私の例では、注文はm8、f8、m12、f12です。それが役に立てば幸い!

+0

私はいくつかの解決策を試してきましたし、 'for()'ループが一番簡単になると思います。あなたが使用できる例については私の編集を参照してください。それが動作することを願って! – LAP

0

は、あなたのデータは次のようになりましょうベースR.とソリューションを好むだろう:性別と年齢の組み合わせに基づいて

dat <- data.frame(code = paste0(LETTERS[1:24], 1:24), sex=c("m", "f"), age=c(8,12, 12, 8), v.1 = sample(1:10, 24, replace=T), v.2 = sample(1:10, 24, replace=T)) 

スプリットとV.1を呼び出しを各分割の値:

lapply(split(dat, list(dat$sex, dat$age)), '[[', "v.1") 

$f.12 
[1] 1 9 2 3 3 10 

$f.8 
[1] 8 3 7 7 3 8 

$m.12 
[1] 10 3 2 2 4 1 

$m.8 
[1] 8 10 1 9 5 7 

分割数は、性別と年齢の組み合わせに基づいており、eac時間分割:

lapply(split(dat, list(dat$sex, dat$age)), '[[', "v.2") 

$f.12 
[1] 10 3 5 8 9 2 

$f.8 
[1] 2 3 4 8 2 5 

$m.12 
[1] 9 7 1 1 1 2 

$m.8 
[1] 5 2 1 5 9 10 

編集:おかげ@Sotosこれはifelse()に簡単であるべき二つの変数

+0

ありがとうございます。外部ベクトルにルックアップを追加するにはどうすればよいですか? –

+0

「外部ベクトルの参照」とはどういう意味ですか? –

+0

2つの変数に対して 'split'を使い、' g'を定義する必要はありません。何か 'lapply(split(dat、sex、dat $ age)) '、[['、 'v.1')' – Sotos

関連する問題