2016-06-28 5 views
1

回答者の指定した友人の識別子を提供するデータがあります。私は仲間の2人の仲間(被仲間の友人ではなく、友人の友人の友人)をリンクさせようとしているので、仲間の成果や特性の影響を与える手段として、回答者。ピアツーピアのリンク:2つのリンクピアの複数のリストの置換

私は2つのリンクピアの識別子を正常にリンクしましたが、2つのリンクピア識別子が1回だけ残されたままにしておきます。たぶん、これは私がそれを作ったよりもはるかに簡単です - 私は最も鮮明で明るいものではありません - しかしこれまでは私は失敗しました。以下では、識別子の玩具データセットと、その作業を試みた段階と、どこに止まっているのかを示します。

私は作業しているセットアップ全体を提供しますが、私が立ち往生しているコードのポイント番号4です。このおもちゃの例では男性2人と女性2人しかリストされていませんが、実際のデータには男性5人と女性5人の友達がリストされています。私が全体のアプローチをより一般的かつ直接的にする方法についてのヒントがあれば、それを聞いていただければ幸いです。

データには、aidが人物識別子です。 mf1aidは男性の友達1などです。私はaidの友達でない友達の友達をaidにリンクする必要があります。初期段階のいくつかはvlookupプログラムが必要です。

これらのパーツは機能しますが、おそらく非効率です。

clear all 
clear mata 
set more off 





input aid mf1aid mf2aid ff1aid ff2aid 
     101 102  103  106 .  
     102 101  104  106 .  
     103 101  104  107 108 
     104 105  102  108 109 
     105 104  101  106 110 
     106 101  102  107 108 
     107 103  .  106 110 
     108 103  104  109 108 
     109 104  101  108 110 
     110 105  104  109 107 

end 

/* The above data is setup so that some aid's name friends who reciprocate and some 
name friends who do not reciprocate the link (as in the real data). */ 




/* Need to link aid's of those 2 links away from each aid 

It must do the following: 
    1. Link the friend `aid`s of each person's friends 
    2. Delete the friend of friends `aid`s that are also the person's 1 link friends 
    3. Delete extra counts of 2 link `aid`s that may occur if a person's friends 
     are all linked to a k `aid` that is not linked to i.   
    4. Delete self from friend of friend links. */ 




// Duplicating friend links because `vlookup.ado` would not link friends of friends id 
forvalues i = 1(1)2 { 

    gen mf`i'aid2 = mf`i'aid 
    gen ff`i'aid2 = ff`i'aid 

} 


/* 
Strategy: 1. use vlookup to attach the friend ids of each aid's friends, 
      so for mf1aid it attaches that friend's mf1aid2, mf2aid2, ff1aid2, and ff2aid2 
      2. delete self links in 2 link set 
      3. delete own friends who are in 2 link set 
      4. drop multiple listings in 2 link set to just 1 listing   

Mf_mf = "male friend male friend" so the male friends of i's male friends 
Mf_ff = "male friend female friend" 
Ff_mf = "female friend male friend" 
Ff_ff = "female friend female friend" 
*/ 


// 1. Using vlookup.ado to link friends friend aids 
forvalues i = 1(1)2 { 

    vlookup mf1aid, gen(Mf1_mf`i'aid) key(aid) value(mf`i'aid2) 
    vlookup mf1aid, gen(Mf1_ff`i'aid) key(aid) value(ff`i'aid2) 

    vlookup mf2aid, gen(Mf2_mf`i'aid) key(aid) value(mf`i'aid2) 
    vlookup mf2aid, gen(Mf2_ff`i'aid) key(aid) value(ff`i'aid2) 

    vlookup ff1aid, gen(Ff1_mf`i'aid) key(aid) value(mf`i'aid2) 
    vlookup ff1aid, gen(Ff1_ff`i'aid) key(aid) value(ff`i'aid2) 

    vlookup ff2aid, gen(Ff2_mf`i'aid) key(aid) value(mf`i'aid2) 
    vlookup ff2aid, gen(Ff2_ff`i'aid) key(aid) value(ff`i'aid2) 
} 

drop mf1aid2-ff2aid2 


// 2. Now Delete self links in friend of friend links 
forvalues i = 1(1)2 { 

    replace Mf1_mf`i'aid = . if Mf1_mf`i'aid == aid 
    replace Mf2_mf`i'aid = . if Mf2_mf`i'aid == aid 

    replace Ff1_mf`i'aid = . if Ff1_mf`i'aid == aid 
    replace Ff2_mf`i'aid = . if Ff2_mf`i'aid == aid 

} 


// 3. Delete friends of friends who are also friends of i 
forvalues i = 1(1)2 { 

    replace Mf1_mf`i'aid = . if Mf1_mf`i'aid == mf1aid | Mf1_mf`i'aid == mf2aid  
    replace Mf1_ff`i'aid = . if Mf1_ff`i'aid == ff1aid | Mf1_ff`i'aid == ff2aid 

    replace Mf2_mf`i'aid = . if Mf2_mf`i'aid == mf1aid | Mf2_mf`i'aid == mf2aid  
    replace Mf2_ff`i'aid = . if Mf2_ff`i'aid == ff1aid | Mf2_ff`i'aid == ff2aid 

    replace Ff1_mf`i'aid = . if Ff1_mf`i'aid == mf1aid | Ff1_mf`i'aid == mf2aid  
    replace Ff1_ff`i'aid = . if Ff1_ff`i'aid == ff1aid | Ff1_ff`i'aid == ff2aid 

    replace Ff2_mf`i'aid = . if Ff2_mf`i'aid == mf1aid | Ff2_mf`i'aid == mf2aid  
    replace Ff2_ff`i'aid = . if Ff2_ff`i'aid == ff1aid | Ff2_ff`i'aid == ff2aid 

} 

ここで私は立ち往生しています。各人の友人の一部が他の友人を共有しているので、私は現在、それぞれの回答者に対して2回以上表示される2つのリンクピアを残しています。

// 4. Replace multiple listings of 2 link peers 



global mfofs "Mf1_mf1aid Mf1_mf2aid Mf2_mf1aid Mf2_mf2aid Ff1_mf1aid Ff2_mf2aid" 
global ffofs "Mf1_ff1aid Mf1_ff2aid Mf2_ff1aid Mf2_ff2aid Ff1_ff1aid Ff2_ff2aid" 




putmata aid Z=(Mf1_mf1aid Mf1_mf2aid Mf2_mf1aid Mf2_mf2aid Ff1_mf1aid Ff2_mf2aid Mf1_ff1aid Mf1_ff2aid Mf2_ff1aid Mf2_ff2aid Ff1_ff1aid Ff2_ff2aid) 

mata: 

/* 
fofa = Z 
for (i=1; i<=rows(Z); i++) { 
    row = fofa[i,]' 
    nvals[i] = length(uniqrows(select(row, (row :< .)))) 
} 
*/ 


// The below is all sorts of wrong 
fof = J(rows(Z), cols(Z), .) 
for (i=1; i<=rows(Z); i++) { 
    for (j=1; j<=cols(Z); j++) { 
     for (k=1; k<=cols(Z); k++) { 
      if (Z[i,j] - Z[i,j+k] !=0) Z[i,j] = Z[i,j] 
     } 
    } 
} 



end 

誰でも私を正しい方向に向けることができますか?

私は、を受け取りました。の機能はegenmoreからrownvals()と呼ばれています。ただし、反復しない値だけを返します。私は、値の最初の式を保持し、繰り返しを欠いている必要があります。

私がこれをうまく説明していない場合は、お詫び申し上げます。混乱するところを教えてください。

答えて

2

は、長い形式でデータを操作することは、通常ははるかに簡単です。

友人の友人のリストが望まれます。そしてリストにある人は一流の友達になれません。サンプルデータでは、aid == 101の場合、101ではない102の唯一のフレンド、または101の第1レベルのフレンドは104です。

以下のコードでは、rangejoin(SSCから)を使用して、各観測の友人を友人とペアにします。

* Example generated by -dataex-. To install: ssc install dataex 
clear 
input float(aid mf1aid mf2aid ff1aid ff2aid) 
101 102 103 106 . 
102 101 104 106 . 
103 101 104 107 108 
104 105 102 108 109 
105 104 101 106 110 
106 101 102 107 108 
107 103 . 106 110 
108 103 104 109 108 
109 104 101 108 110 
110 105 104 109 107 
end 

* convert to long form 
rename aid id 
reshape long @aid, i(id) j(mfn) string 
drop if mi(aid) 
drop mfn 
isid id aid, sort 

* save each id's list of friends 
save "friends.dta", replace 

* first level of friends 
rename aid friend1 

* pair each observation with using obs where id is the same as friend1 in current obs 
rangejoin id friend1 friend1 using "friends.dta" 
rename aid friend2 
drop *_U friend1 

* remove self and duplicates 
drop if id == friend2 
bysort id friend2: keep if _n == 1 

* remove those are are first level friends 
rename friend2 aid 
merge 1:1 id aid using "friends.dta", keep(master) nogen 
+0

ロバートこれは私のアプローチよりもはるかに効率的であり、感謝@ダニエル。しかし、私は2つのリンクで区切られたピアを意味する真のピアを必要としています。ノードiの集合{i、j、k}について、iがjにリンクされ、jがkにリンクされているが、iとkがリンクされていない場合、私はjとkのfriend2としてkを必要とする。だから、friend2の場合、friend1の下にも表示される人は、見つからない、または落ちるように設定する必要があります。私は今これに取り組んでいます。もし私がそれを理解したら、私はその変化に気づくでしょう。ご協力いただきありがとうございます! – Jonathan

+0

私が正しく理解すれば、これはもっと簡単です。私はそれに応じてコードを調整しました。結局のところ、あなたは友人の友人を見つけて、第一級の友人には合わないものを単に保ちます。 –

+0

はい、それは正しいですし、アプローチは素晴らしいです。私はあなたの答えをアップに投票しますが、明らかに私はまだ許可されていません。 – Jonathan

0

これらの変数をすべて一行に格納している場合(これはコードと名前を使用しているようです)、これを長いデータセットに再作成し、重複コマンドの1つを使用して重複。

注:これはおそらく、コメントではなく、答えなければなりませんが、私はそれを行うための評判を持っていない...示唆しているダニエルよう

関連する問題