2012-02-28 9 views
0

この問題にどのように接近するかを正確に把握しておらず、次のコードについては、私は以下の結果を望んでいます。結果は、以下の基準に基づいている:同じ日以内[R]で複数の基準を持つ新しい列を定義する方法(ddply内のループの場合)


idEffectA:
を常に0 ID「以外のID A」行の
1行の有する任意の行のIDが存在する場合「非のid A」行のその日付
0のための特別な1すべてのid Aの行は、その日

sizeEffect10のために特別に0を持っている場合:非」の場合は常に0サイズ10
1行の
サイズが10インチの行があれば10インチの行があり、その中には特別なものが1つあります日付
すべてのサイズ10がその日付で特別な0を持つ場合、「非サイズ10」行の場合は0

同様に、他の変数の場合も同様です。列の名前を生成することもできれば、それぞれを手動で定義する必要はなく、非常に便利です。また、実際のデータセットでは、サイズとIDにはさまざまなカテゴリがありますので、それらを関数に入力するのを避けるのが最善ですが、唯一の可能性がある場合は、マージで使用される集計関数をデータに使用できます定義された関数で設定します(その他の提案は?)。結果の列を元のデータセットにバインドしたいと思います。

実際に私が列で欲しいものを定義するのが難しいので、ご不明な点がありましたら教えてください。私は索引付けと一緒にplyrパッケージを使用しようとしましたが、それほど遠くには達していません。ありがとう!最初の部分については、私はこのようなものは、ループ内で働くことができると思い

i=0 
ifelse(id==A & max(special[id=="A" & date==min(date)+i], 1, 0) 
i=i+7 

しかし、その後私は本当にわからないんだけど...ここ

 original.data 
    label date special size id 
    1 1/11/2012 0 10 A 
    2 1/11/2012 1 20 A 
    3 1/11/2012 0 10 B 
    4 1/11/2012 0 30 C 
    5 1/11/2012 0 10 C 
    1 1/18/2012 0 10 A 
    2 1/18/2012 0 20 A 
    3 1/18/2012 0 10 B 
    4 1/18/2012 1 30 C 
    5 1/18/2012 1 10 C 
    1 1/25/2012 1 10 A 
    2 1/25/2012 1 20 A 
    3 1/25/2012 0 10 B 
    4 1/25/2012 1 30 C 
    5 1/25/2012 1 10 C 
    1 2/1/2012 0 10 A 
    2 2/1/2012 1 20 A 
    3 2/1/2012 1 10 B 
    4 2/1/2012 0 30 C 
    5 2/1/2012 0 10 C 
    1 2/8/2012 0 10 A 
    2 2/8/2012 0 20 A 
    3 2/8/2012 0 10 B 
    4 2/8/2012 1 30 C 
    5 2/8/2012 0 10 C 
    1 2/15/2012 1 10 A 
    2 2/15/2012 1 20 A 
    3 2/15/2012 0 10 B 
    4 2/15/2012 1 30 C 
    5 2/15/2012 0 10 C 

があります私が探しています結果:

 results 
    idEffectA sizeEffect10 idEffectB sizeEffect20 idEffectC sizeEffect30 
    0 0 0 1 0 0 
    0 0 0 0 0 0 
    1 0 0 1 0 0 
    1 0 0 1 0 0 
    1 0 0 1 0 0 
    0 0 0 0 1 1 
    0 1 0 0 1 1 
    0 0 0 0 1 1 
    0 1 0 0 0 0 
    0 0 0 0 0 1 
    0 0 0 1 1 1 
    0 1 0 0 1 1 
    1 0 0 1 1 1 
    1 1 0 1 0 0 
    1 0 0 1 0 1 
    0 0 1 1 0 0 
    0 1 1 0 0 0 
    1 0 0 1 0 0 
    1 1 1 1 0 0 
    1 0 1 1 0 0 
    0 0 0 0 1 1 
    0 0 0 0 1 1 
    0 0 0 0 1 1 
    0 0 0 0 0 0 
    0 0 0 0 0 1 
    0 0 0 1 1 1 
    0 1 0 0 1 1 
    1 0 0 1 1 1 
    1 1 0 1 0 0 
    1 0 0 1 0 1 

[OK]を、ここで私が持っているものに始まりです。

年代を作成した私は、このコードを実行することを期待して
x <- rep(0, length(id)) 
i=min(date) 
n=1 
id.level = 1 

for(i in min(date):max(date)){ 
    for(id.level in 1:length(levels(id))){ 
     for(n in 1:length(id)){ 
      x[n] <- ifelse(max(special[id==id[id.level] & date==i])==1, 0, 1) 
      n=n+1 
     } 
     y <- paste("idEffect",id[id.level]) 
     id.level = id.level + 1 
     colnames(x)[length(colnames(x))] <- y 
    } 
    i=i+7 
} 

すべてのidの私は、元の記事に書いたような:

idEffectA:常に
0 ID

と行の個別のIDごとに列を作成します。しかし、私は他の条件やそれをどのように適合させるべきかわからない。ネストされたifelseステートメントで追加する必要がありますか?どんな助けでも大歓迎です。私は、Rでの索引付けの作業に慣れているので、ifelseやfor文についての知識はあいまいです。ありがとう。

+0

@BrianDiggsなぜ私はコードを編集してforループの変数の初期化を取り除くのか混乱しています。説明してください。 – user1228982

+0

それは事故だった。私はそのコードを外すことを意味しませんでした。私は、既存のコードを再フォーマット/インデントすることを意味しました。書式設定されたコードを貼り付けたときにあまりにも多くを選択しました。私はそれを修正しました。エラーを申し訳ありません。 –

+0

今後、自分のコードを入力するためのより良い方法がありますか? – user1228982

答えて

2

最初に、データを再現可能な形式にします(私はoriginal.datadput()を使用しましたが、あなたが持っていたものから読み込み、いくつかの変換を行いました)。これにより、すべてのデータ型が正しいことが確認されます(dateDateで、idfactorなどですが、これらは関連しています)。)

original.data <- 
structure(list(label = c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 
5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 
1L, 2L, 3L, 4L, 5L), date = structure(c(15350, 15350, 15350, 
15350, 15350, 15357, 15357, 15357, 15357, 15357, 15364, 15364, 
15364, 15364, 15364, 15371, 15371, 15371, 15371, 15371, 15378, 
15378, 15378, 15378, 15378, 15385, 15385, 15385, 15385, 15385 
), class = "Date"), special = c(0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 
1L, 1L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 
0L, 1L, 1L, 0L, 1L, 0L), size = c(10L, 20L, 10L, 30L, 10L, 10L, 
20L, 10L, 30L, 10L, 10L, 20L, 10L, 30L, 10L, 10L, 20L, 10L, 30L, 
10L, 10L, 20L, 10L, 30L, 10L, 10L, 20L, 10L, 30L, 10L), id = structure(c(1L, 
1L, 2L, 3L, 3L, 1L, 1L, 2L, 3L, 3L, 1L, 1L, 2L, 3L, 3L, 1L, 1L, 
2L, 3L, 3L, 1L, 1L, 2L, 3L, 3L, 1L, 1L, 2L, 3L, 3L), .Label = c("A", 
"B", "C"), class = "factor")), .Names = c("label", "date", "special", 
"size", "id"), row.names = c(NA, -30L), class = "data.frame") 

次に、「同じ日付内」の処理を行いたいとします。これは、分割適用結合戦略を意味する。 plyrライブラリはこの井戸を扱います。

library("plyr") 

あなたはddplydata.frameうち、中data.frame)をしたい、あなたは、単一の日付に対応するデータのサブセットのためにあなたの変換を行う機能を必要としています。 Aの値に対応するspecial値のいずれかが1であれば、idEffectAについて

ddply(original.data, .(date), function(DF) { 
    # idEffectA 
    others <- if(any(DF$special[DF$id == "A"] == 1)) {1} else {0} 
    DF$idEffectA <- ifelse(DF$id == "A", 0, others) 
    # sizeEffect10 
    others <- if(any(DF$special[DF$size == 10] == 1)) {1} else {0} 
    DF$sizeEffect10 <- ifelse(DF$size == 10, 0, others) 
    DF 
}) 

othersチェックを、そして:あなたのルールは次のようになり実装、あなたの最初の2つの例(idEffectAとsizeEffect10)を使用

その場合は1、その他の場合は0です。 idEffectAへの割り当ては、それがA0)であるかどうか(任意のothersと判定されたもの)であるかどうかを条件とします。大きさは論理を繰り返しますが、数値と比較してください。

この例では、可能な値のそれぞれの列に、idsizeを追加することを示しています。ループでそこに行くことができます。与え

allid <- levels(original.data$id) 
allsize <- unique(original.data$size) 
ddply(original.data, .(date), function(DF) { 
    for (e in allid) { 
     others <- if(any(DF$special[DF$id == e] == 1)) {1} else {0} 
     DF[[paste("idEffect",e,sep="")]] <- ifelse(DF$id == e, 0, others) 
    } 
    for (e in allsize) { 
     others <- if(any(DF$special[DF$size == e] == 1)) {1} else {0} 
     DF[[paste("sizeEffect",e,sep="")]] <- ifelse(DF$size == e, 0, others) 
    } 
    DF 
}) 

label  date special size id idEffectA idEffectB idEffectC sizeEffect10 sizeEffect20 sizeEffect30 
1  1 2012-01-11  0 10 A   0   0   0   0   1   0 
2  2 2012-01-11  1 20 A   0   0   0   0   0   0 
3  3 2012-01-11  0 10 B   1   0   0   0   1   0 
4  4 2012-01-11  0 30 C   1   0   0   0   1   0 
5  5 2012-01-11  0 10 C   1   0   0   0   1   0 
6  1 2012-01-18  0 10 A   0   0   1   0   0   1 
7  2 2012-01-18  0 20 A   0   0   1   1   0   1 
8  3 2012-01-18  0 10 B   0   0   1   0   0   1 
9  4 2012-01-18  1 30 C   0   0   0   1   0   0 
10  5 2012-01-18  1 10 C   0   0   0   0   0   1 
11  1 2012-01-25  1 10 A   0   0   1   0   1   1 
12  2 2012-01-25  1 20 A   0   0   1   1   0   1 
13  3 2012-01-25  0 10 B   1   0   1   0   1   1 
14  4 2012-01-25  1 30 C   1   0   0   1   1   0 
15  5 2012-01-25  1 10 C   1   0   0   0   1   1 
16  1 2012-02-01  0 10 A   0   1   0   0   1   0 
17  2 2012-02-01  1 20 A   0   1   0   1   0   0 
18  3 2012-02-01  1 10 B   1   0   0   0   1   0 
19  4 2012-02-01  0 30 C   1   1   0   1   1   0 
20  5 2012-02-01  0 10 C   1   1   0   0   1   0 
21  1 2012-02-08  0 10 A   0   0   1   0   0   1 
22  2 2012-02-08  0 20 A   0   0   1   0   0   1 
23  3 2012-02-08  0 10 B   0   0   1   0   0   1 
24  4 2012-02-08  1 30 C   0   0   0   0   0   0 
25  5 2012-02-08  0 10 C   0   0   0   0   0   1 
26  1 2012-02-15  1 10 A   0   0   1   0   1   1 
27  2 2012-02-15  1 20 A   0   0   1   1   0   1 
28  3 2012-02-15  0 10 B   1   0   1   0   1   1 
29  4 2012-02-15  1 30 C   1   0   0   1   1   0 
30  5 2012-02-15  0 10 C   1   0   0   0   1   1 

I事前計算それは一度だけ行われる必要があるためidsizeallidallsize)の可能な値を。各日付の関数内で、可能な値のそれぞれを繰り返します(id)。同じ方法で "効果"列を作成しますが、pasteを使用して列名を作成します。

+0

うわー、それは私が働いていたよりずっと簡単でした!ありがとう@ブライアン。私はそれを通ってすべてを捕らえなければならないだろうが、これがうまくいくと確信している。私はちょうど2年の休憩の後にRに戻っているので、私はまだ知りません/すべてのトリックを覚えています。あなたのコードは間違いなく私が学ぶのを助けます! – user1228982

関連する問題