4

次のようなデータフレームがあります。

         date      time userid        status
1  02/25/2012  09:22:10   aabc     logged_in
2  02/25/2012  09:30:10   aabc    logged_out
3  02/25/2012  09:29:20   abbc    logged_out
4  02/25/2012  09:27:30    abc     logged_in
5  02/25/2012  09:26:29    abc  login_failed
6  02/25/2012  09:26:39    abc  login_failed
7  02/25/2012  09:26:52    abc  login_failed
8  02/25/2012  09:27:09    abc  login_failed
9  02/25/2012  09:27:20    abc  login_failed
10 02/25/2012  09:24:10   abdc     logged_in
11 02/25/2012  09:24:12   abdc    logged_out
12 02/25/2012  09:22:10   abhc     logged_in
13 02/25/2012  09:30:10   abuc     logged_in
14 02/25/2012  09:30:14   abuc    logged_out
15 02/25/2012  09:29:40    baa     logged_in

各ユーザーIDのlogin_failuresのユーザーID、ステータス、および「カウント」が必要です。これは私がしました:

ddply(mytbl, c('userid', 'status'), function(x) c(count=nrow(x)))、しかし、これはすべてのユーザーIDの数を示します。出力を、ステータスが「login _failed」のユーザー ID のみに制限したいと考えています。何か案は?数値フィールドによるグループ化に関する質問を見たことがありますが、文字列に関する質問はありません。

私はプライアのすべての機能に精通しているわけではありません。要約、集約、sqldf、data.table などを使用してこれを行う方法を確認するのは素晴らしいことです。それぞれをゆっくりと理解してください。

ありがとうスリ

4

4 に答える 4

5
require(data.table)
DT = as.data.table(mytbl)

DT[status=="login_failed", .N, by=userid]

列に名前を付けるには:

DT[status=="login_failed", list(failed_logins=.N), by=userid]
于 2012-10-03T20:17:11.287 に答える
2

これは、以下を使用したベースRソリューションaggregate()です。

setNames(aggregate(status ~ userid,
                   mytbl[mytbl$status == "login_failed", ],
                   function(x) length(x)),
         c("userid", "failed_logins"))
#   userid failed_logins
# 1    abc             5

アップデート

頭に浮かぶもう1つの便利な機能はave()、次のように使用できることです。

  • まず、を使用ave()して、各ユーザーによる各アクティビティの実行カウントを取得する新しい列をデータセットに追加します。(:「userid」列と「status」列が文字クラスであることを確認する必要がありました。これを機能させるための要素ではありません)。

    mytbl$status_seq <- ave(mytbl$status, mytbl$userid, 
                            mytbl$status, FUN = seq_along)
    head(mytbl)
    #         date     time userid       status status_seq
    # 1 02/25/2012 09:22:10   aabc    logged_in          1
    # 2 02/25/2012 09:30:10   aabc   logged_out          1
    # 3 02/25/2012 09:29:20   abbc   logged_out          1
    # 4 02/25/2012 09:27:30    abc    logged_in          1
    # 5 02/25/2012 09:26:29    abc login_failed          1
    # 6 02/25/2012 09:26:39    abc login_failed          2
    
  • 次に、aggregate()前に示したように使用し、関心のある条件をサブセット化して、max値を取得します。

    aggregate(status_seq ~ userid, 
              mytbl[mytbl$status == "login_failed", ],
              function(x) max(x))
    #   userid status_seq
    # 1    abc          5
    
    aggregate(status_seq ~ userid, 
              mytbl[mytbl$status == "logged_out", ],
              function(x) max(x))
    #   userid status_seq
    # 1   aabc          1
    # 2   abbc          1
    # 3   abdc          1
    # 4   abuc          1
    

ave()使用した場合はさらに興味深いかもしれないことに注意してください

mytbl$status_seq <- ave(mytbl$status, mytbl$date, mytbl$userid, mytbl$status, 
                        FUN = seq_along)

これにより、データセット内の新しい日ごとにカウンターがリセットされます。

最後に(あまりにも明白かもしれない解決策を共有するリスクがあります)、あなたはカウントだけに興味があるので、あなたは探求したいかもしれませんtable()、それはあなたに一度にすべての情報を与えます:

table(mytbl$userid, mytbl$status)
# 
#      logged_in logged_out login_failed
# aabc         1          1            0
# abbc         0          1            0
# abc          1          0            5
# abdc         1          1            0
# abhc         1          0            0
# abuc         1          1            0
# baa          1          0            0
于 2012-10-03T18:25:14.513 に答える
2

@Maiasaura とは少し異なるアプローチ。失敗したログインのみにフィルターをかけ、要約します。違いはuserid、ログインはあるが失敗したログインがないものが最終結果に 0 で表示されるかどうかです。

ddply(mytbl[mytbl$status=="login_failed",], .(userid), 
  summarise, failed_logins=length(status))

これは与える

> ddply(mytbl[mytbl$status=="login_failed",], .(userid), 
+   summarise, failed_logins=length(status))
  userid failed_logins
1    abc             5

アプローチを完了するには、すべての 's が必要な場合userid:

ddply(mytbl, .(userid), 
  summarise, failed_logins = sum(status=="login_failed"))

を与える

> ddply(mytbl, .(userid), 
+   summarise, failed_logins = sum(status=="login_failed"))
  userid failed_logins
1   aabc             0
2   abbc             0
3    abc             5
4   abdc             0
5   abhc             0
6   abuc             0
7    baa             0
于 2012-10-03T18:16:26.403 に答える
2
ddply(mytbl, .(userid), transform, 
failed_logins = length(which(status=="login_failed")))

Brian Diggs の指摘に続き、元のデータセットにこの情報を追加する必要があると想定したため、上記を書きました。そうでなく、要約だけが必要な場合は、に置き換えtransformますsummarise

于 2012-10-03T18:10:58.047 に答える