-3

name と action_id の 2 つの列を持つデータ フレームがあります。多くの場合、名前には複数の action_id があり、action_id は次のように複数の名前にも関連付けられています。

name action_id
Bob  1
Bob  2
Bob  3
Tom  2
Tom  1
Bill 1
Bill 3

これが私の問題です。名前に基づいて、action_ids 間の重複にインデックスを付けようとしています。したがって、ある名前が 2 つの action_id に関連付けられ、別の名前が同じ 2 つの action_id に関連付けられている場合、これら 2 つの action_id 間の重複は 1 です。上記のデータの場合、この関数は action_id 1 と 2 の間の重複 1 を返します。 1 から 3 の間、他の潜在的なオーバーラップの場合は 0 です。次のように、すべての潜在的な action_id オーバーラップとそれらのオーバーラップのインスタンスを含むデータ テーブルを描いています。

  1 2 3
1 - 0 0 
2 1 - 0
3 1 0 -

ユーザーに関連付けられたすべての action_ids をインデックス化するデータ テーブルにデータ フレームを変換することでこれに対処しようとしましたが、上記のようにそのデータ テーブルを action_id のみのテーブルに変換すると問題が発生します。

すべてのデータをループすることを考えましたが、何百万もの行を扱っています.for/ifループはここでは時間効率が悪いので、ベクトルベースの解決策を見つけようとしています.

4

1 に答える 1

2

これは、あなたが望む方法でオーバーラップを計算すると思います:

overlap = function(df, id1, id2) {
  id_by_name = tapply(df$action_id, df$name, unique)
  ids_in_name = lapply(
    id_by_name,
    function(x) {
      all(c(id1, id2) %in% x)
    }
  )
  overlapping_names = names(ids_in_name)[unlist(ids_in_name)]
  if (length(overlapping_names) >= 2) {
    return(1)
  } else {
    return(0)
  }
}

出力:

> overlap(df, 1, 2)
[1] 1
> overlap(df, 2, 3)
[1] 0
于 2013-03-12T01:40:44.460 に答える