0

Rでやりたいことを実行するための最良の方法について少し迷っています。

いくつかの列を持つデータフレームがあります。それらの1つは、ユーザーと他の列、たとえば番号(0,1,2,3,4,5)です。ユーザーが繰り返されることもありますが、この場合、列番号には一連の番号が必要です。このようなものにすることができます:

user number  column B column C
1    0        85      200
2    1        165     852
1    2        200     1000
3    0        15      689
3    1        89      896
4    0        78      582
4    2        96      586 

私が入手したいのは:

user number status days
1    0      0       200
3    0      1       50 ->(value column C, user 3, number 1)-(value column B, user 3, number 0)
4    0      0       200

これらのユーザーからの値に基づいて、データフレームに2つの列を追加したいと思います。

  • ユーザーが番号==0であるが、ユーザーが一意のステータス==0および日数==事前定義された番号である場合
  • ユーザーの番号が0で、ユーザーが一意でない場合
    • ユーザーの2番目の出現に数値==1、ステータス== 1があり、日数は値列Cからの減算である必要がありますユーザーの2番目の出現-値列Bユーザーの最初の出現
    • ユーザーの2回目の出現に番号!= 1、ステータス== 0、日数==事前定義された番号がある場合
  • 番号==0を持たないユーザーをデータセットから削除します

私はこれを行うための最良の方法について少し混乱しているので、この質問をしています。number == 0のデータフレームをサブセット化してから、データフレーム間でユーザーを比較して繰り返しユーザーを確認しますが、これを行うにはおそらく最善の方法ではありません。

どんな指針やアイデアも素晴らしいでしょう!

ご協力ありがとうございました

編集

columnBは、「2002-01-01」から経過した日数です。たとえば、最初のユーザーは2002-01-01から85日後にデータフレームに入力します

columnCは、ユーザーが監視を続けた日数です。それらの日を過ぎると、ユーザーはデータベースに存在しなくなります。

EDIT2

私のデータセットには36列と26075行があります

いくつかの提案の後、私がこれまでに持っているものはどこにありますか。

#remove from dataset all users that don't have number == 0
df1 <- df[df$user %in% df[df$number == 0,1],]

df1["Status"] <- 0

#doesn't work
df1[df1$number == 1 %in% df1[duplicated(df1$user),]]

私がやろうとしていたのは、重複しているすべてのユーザーを見つけて、その数が1に等しいかどうかを確認することです。後でこのようなことを試すには、次のようにします。

 df1[df1$number == 1 %in% df1[duplicated(df1$user),]] <- df1$Status == 1
4

2 に答える 2

1
 #order the dataset by columns needed
 df2 <- df2[order(df2$user, df2$number),]

 ids <- unique(df2$user)

 #create variable status and days
 status <- NULL
 end <- NULL
 for (i in 1:length(ids)) {
     aux <- df2[df2$user %in% ids[i],]
     if (nrow(aux) == 1 & aux$number[1] == 0){
          status[i] <- 0
          days[i] <- end
     } else if (nrow(aux) > 1) {
          status[i] <- 1
          days[i] <- aux$Event[2]
     } else {
          status[i] <- NA
          days[i] <- NA
     }
 }

 #merge the vector created with the database
 data <- data.frame(ids, status, days)
 df2 <- df2[!duplicated(df2$user),]
 df2 <- merge(df2, data, by.x="user", by.y="ids")

 #remove NAs from the dataset
 df.f <- df2[!(is.na(df2$days)),]
于 2013-01-22T09:11:40.530 に答える
1

おそらく、各ユーザーごとに data.frame をサブセット化することは最も効率的な方法ではありませんが、数秒で回答が必要ない場合は、データ量には十分かもしれません。

ids = unique(df1$user);
status.days = sapply(ids,function(id) {
   udf = subset(df1,subset= user == id);
   if (nrow(udf) == 1) {
     status = 0;
     days = XXX; # the predefined value.
   } else if (udf$number[2] != 1) {
     status = 0;
     days = XXX; # the predefined value;
   } else {
     status = 1;
     days = udf$columnC[2] - udf$columnB[1];
   }
   c(status,days)
});

status = sapply(status.days,simplify=T,function(sd) { sd[1] });
days = sapply(status.days,simplify=T,function(sd) { sd[2] });

result = data.frame(user=ids,number=rep(0,length(ids)),status=status,days=days)

一時的なリスト「status.days」からステータスと日を抽出するためのインデックス作成について確信が持てないことを告白しなければなりません...おそらくsd [1]とsd [2]の代わりに、sd [1] [1にする必要があります] 、sd[1][2] または sd[[1]][1]、sd[[1]][2]

于 2013-01-11T13:59:05.910 に答える