2017-02-03 44 views
0

編集:私は、アカウントのリストを持っているは条件付きwhileループRで

をrewording: < accountdf - 私はこのリストをまとめる

Account Owner Value 
Acc1 Jeff 500 
Acc2 Jeff 100 
Acc3 Jeff 200 
Acc4 Jeff 700 
Acc5 Matt 400 
Acc6 Matt 500 
Acc7 Matt 600 
Acc8 Matt 20 
Acc9 Matt 80 
Acc10 Matt 1400 
Acc11 Cindy 50 
Acc12 Cindy 50 
Acc13 Cindy 150 
Acc14 Cindy 600 
Acc15 Cindy 600 
Acc16 Cindy 1350 
Acc17 Cindy 800 
Acc18 Cindy 400 
Acc19 Sarah 1500 
Acc20 Sarah 3000 
Acc21   1000 
Acc22   400 
Acc23   500 
Acc24   800 
Acc25   900 

とき、私はアカウントの数との合計値のこの概要を取得アカウント

namesummarydf < -

Name Accounts Value 
Jeff 4   1500 
Matt 6   3000 
Cindy 8   4000 
Sarah 2   3500 
Mark 0   0 

私はMarkを追加しました。彼は今、アカウントの所有者になりますが、彼は現在アカウントを持っていません。

最初のステップは、誰もが持つべきアカウントの平均を見ることです。 25人のアカウントと5人のオーナーがいるので、誰もが5つのアカウントを持つべきです。合計金額は15,600であり、所有者は5人であるため、アカウントの金額は約3,120人です。これは見積もりなので、ちょっと離れていても問題ありません。 (私の実際のデータには私は300人のオーナーと80,000人のアカウントがあり、そのうちのいくつかは所有しているものと所有していないものがあります)

誰もが5つのアカウントを持っているはずですから、 /またはあまりにも多くの値(3120以上)。 Mattには3000件のアカウントがあり、Cindyには4000件の価値があり、Sarahには3500件のアカウントが2つあります。

私がしようとしていたのはfor-loopであり、要約リストの各名前、彼らが平均以上の口座または平均以上の価値を持っているかどうかを調べました。はいの場合は、勘定科目リストで名前の勘定科目のみを調べ、四分位数の範囲内でランダムに1つを選択します。 このランダムな選択は、具体的には、大きな値のアカウント、中位の値または低い値を取り除くことであり、完全にランダムではありません。私は20%のパーセンタイルと40%のパーセンタイルの間でアカウントのサンプルを取って、高い価値のアカウントを損なわれないようにしたかったのです。パーセンタイル範囲は各アカウントの$$となります。

誰かが$ 50から$ 10000の範囲の口座を持っていた場合、20%と40%は個々の口座価値の$ 2,000〜$ 4,000の範囲になります。

whileループは1つのランダムなアカウントを削除し、新しいカウントとその人の名前の合計値を振り返ります(今はアカウントが1つ少なくなり、値が$ 2,000未満です)。その後、それが平均を上回っているかどうかを確認し、しきい値に達するまで継続的にアカウントを削除します。これはすべての人にとってこれを行うため、アカウント数が少なくて$$が少なくなるまで、人々の名前からアカウントを体系的に削除します。

私がすでに把握している次のステップは、所有者のいない勘定科目の勘定科目リストを繰り返し、その名前に関連付けられた最低額の人物に割り当てるforループです。

whileループの問題は、私が見て、その人が5つ以上のアカウントを持っているかどうか、または平均$$ sより多いかどうかを確認することでした。たとえば、Sarahは2つのアカウントを持っていますが3500を持っています。彼女のリストから1つの高価値アカウントを削除して、5つのアカウントのクォータを補うために小さいアカウントを割り当てる余裕があります。

for (p in 1:nrow(namesummarydf)){ 

    nameidx <- namesummarydf$Name[p] 

    while (namesummarydf$count[p] > mean(namesummarydf$count) | namesummarydf$Value[p] > mean(namesummarydf$Value)){ 
    sample(accountdf , which(accountdf$Owner == nameidx & 
          (accountdf$totalnewcovalue > quantile(accountdf$Value, prob = 0.15) & 
           accountdf$totalnewcovalue < quantile(accountdf $Value, prob = 0.45))), 1) 
    } 
} 
+0

によってそれら二つをマージ1つのdata.frameを作成します。あなたは質問を明確に表現できますか?再現性のあるデータを共有しますか?あなたの番号のドル記号とカンマはちょうど途中にあります。コピー可能なサンプル入力と、その入力に必要な出力を与えると、より迅速にヘルプを得ることができます。 [データを再現可能に共有するためのヒントについては、こちらを参照してください。](http://stackoverflow.com/q/5963269/903061): 'dput'を使用してコードをシミュレートします。 – Gregor

+0

また、 'while'ループを削除するか、なぜ/間違っているのかを詳しく調べてください。最初のwhileループとwhileループの違いについてもコメントしてください。最初のものは '|'を使いますが、実際のものは '&'を使います。 – Gregor

+0

このためにループする必要はありません。ベクトル化された 'merge'、' match'、 'ifelse'で' aggregate'が動作するかもしれません。 * count *と* value *列の平均と分位数を調べているようですが、* unassign *の意味は明確ではありません。 – Parfait

答えて

0

この擬似コードを利用してみてください:

df1<-data.frame(
N  Q  M1 
Sarah 44 $110,000 
Jeff 111 $541,000 
Cameron 46 $201,000 
Matt 0  $0 
Cindy 0  $0 
) 

df2<-data.frame(
A  N  M2 
Acc1 Sarah $1,200 
Acc2 Sarah $900 
Acc3 Jeff  $700 
Acc4 Cameron $880 
Acc5 Jeff  $4,500 
) 

merge(df1, df2)

それが列N(両方のデータフレームで列のみ)

+0

私のフレーズはちょっとだったと思います。私はデータをマージしようとはしませんが、名前リスト(あなたのdf1)を繰り返し、すべての個々のアカウント(自分のdf2)を見て、スコアが高すぎる場合は名前(N列)をNA値に変えます。 –