2017-09-27 23 views
2

からの同時出現マトリックスを形成:各行の私は次のようになり、データフレームを持つデータフレーム

id val 
1 a 
1 b 
2 a 
2 c 
2 d 
3 a 
3 a 

思うidを持ついくつかの観察に与えられたラベル、ヴァル、など。

私は最終的に取得したいが、私は、各文字がお互いの文字で同じID内に出現回数のカウントを取得する場所次のようになり「共出現」行列である:

a b c d 
a 1 1 1 1 
b 1 0 0 0 
c 1 0 0 1 
d 1 0 1 0 

私はこれを行う方法を探して私の脳を悩まされてきましたが、これまで空になってきました。何かヒント?好ましくは、整頓ツールを使用するが、この時点で他のオプションも開く。

EDIT:この場合、可能な複製としてリンクされている質問への解決策は機能しません。理由は分かりませんが、3つの列を持つデータフレームを持つ質問に関係していると思われます。

+2

[共起行列を作成する]の可能複製(https://stackoverflow.com/questions/13281303/creating-co-occurrence-matrix) – missuse

+1

その質問5歳ですので、今すぐもっと簡単な解決策があることを願っています。私は2つまたは3つのソリューションを試してみましたが、どちらもうまくいきませんでしたので、私の質問は違うかもしれません(第3の列がないためかもしれません) –

+0

私のオリジナルソリューションは@ d.b'sと非常に似ている私はいくつかの価値を追加するためにそれを変更しました。 – useR

答えて

1

ここでは、非常にエレガントないベースR.におけるソリューションですけど

temp = data.frame(do.call(cbind, lapply(split(df, df$id), function(a) 
    combn(a$val, 2))), stringsAsFactors = FALSE) 
sapply(sort(unique(df$val)), function(rows) 
    sapply(sort(unique(df$val)), function(cols) 
     sum(sapply(temp, function(x) 
      identical(sort(x), sort(c(rows, cols))))))) 
# a b c d 
#a 1 1 1 1 
#b 1 0 0 0 
#c 1 0 0 1 
#d 1 0 1 0 

OR igraphdplyr +と

temp = t(do.call(cbind, lapply(split(df, df$id), function(a) combn(a$val, 2)))) 
library(igraph) 
as.matrix(get.adjacency(graph(temp, directed = FALSE))) 
# a c b d 
#a 1 1 1 1 
#c 1 0 0 1 
#b 1 0 0 0 
#d 1 1 0 0 

DATA

df = structure(list(id = c(1L, 1L, 2L, 2L, 2L, 3L, 3L), 
        val = c("a", "b", "a", "c", "d", "a", "a")), 
       .Names = c("id", "val"), 
       class = "data.frame", 
       row.names = c(NA, -7L)) 
0

溶液とを動作するようですpurrr

library(dplyr) 
library(purrr) 
df %>% 
    split(.$id) %>% 
    map_dfr(function(x){ 
    t(combn(x$val, 2)) %>% 
     data.frame(stringsAsFactors = FALSE) 
    }) %>% 
    mutate_all(funs(factor(., levels = c("a", "b", "c", "d")))) %>% 
    table() %>% 
    pmax(., t(.)) 

結果:

X2 
X1 a b c d 
    a 1 1 1 1 
    b 1 0 0 0 
    c 1 0 0 1 
    d 1 0 1 0 

  1. Iは、第一各combn機能をマッピングするpurrrからmap_dfrを用い、その後、idによってdfを分割idグループ。
  2. combnは、ベクトル内の要素のすべての組み合わせを見つけ(length(vec)choose 2)、行列を返します。
  3. _dfrの末尾にあるmap_dfrは、結果がリストの各要素をバインドする行ごとのデータフレームになることを意味します。これは事実上do.call(rbind, lapply())です。
  4. mutate_allは、tableが文字が列に存在しない場合でも必要なすべてのレベルを保持するsuresを作成します。
  5. 最後に、上三角行列が生成されるtableステップ、後ので、私はpmax
  6. pmaxにその行列とその転置を給電する2つの入力からの平行最大値を見つけ、必要に応じて対称行列を返します。

データ:

df = read.table(text= "id val 
       1 a 
       1 b 
       2 a 
       2 c 
       2 d 
       3 a 
       3 a", header = TRUE, stringsAsFactors = FALSE) 
関連する問題