我有一个数据集,其中包括学生的所有要点和其他变量。
我还有一个对角矩阵,其中包含哪个学生是另一个学生的同伴的信息。
现在我想使用第二个矩阵(网络)来计算每个学生的平均对等点。每个人都可以拥有不同(数量)的同伴。 为了计算平均值,我将简单的0,1矩阵重新计算为百分比,其中分母是一个学生所拥有的同伴数量的总和。
然后第二个矩阵看起来像这样:
ID Points Peers
ID1 45 11
ID2 42 33.5
ID3 25 26.5
ID4 60 26.5
ID5 11 43.33
每个学生的分数是另一个数据集中的一个简单变量,我希望将peer-average-points作为第二个变量:
nwcommands
Stata中是否有针对该问题的命令?我目前正在调查Stata命令{{1}},但我不确定它是否可以提供帮助。我可以使用Stata和R的解决方案。
答案 0 :(得分:3)
如果没有过于创意,您可以使用reshape
,collapse
以及Stata中的几个merge
来完成您要执行的操作。一般来说,长格式的数据更容易用于此类练习。
以下是产生所需结果的示例。
/* Set-up data for example */
clear
input int(id points)
1 45
2 42
3 25
4 60
5 11
end
tempfile points
save `points'
clear
input int(StudentId id1 id2 id3 id4 id5)
1 0 0 0 0 1
2 0 0 1 1 0
3 0 1 0 0 1
4 0 1 0 0 1
5 1 0 1 1 0
end
/* End data set-up */
* Reshape peers data to long form
reshape long id, i(Student) j(PeerId)
drop if id == 0 // drop if student is not a peer of `StudentId`
* create id variable to use in merge
replace id = PeerId
* Merge to points data to get peer points
merge m:1 id using `points', nogen
* collapse data to the student level, sum peer points
collapse (sum) PeerPoints = points (count) CountPeers = PeerId, by(StudentId)
* merge back to points data to get student points
rename StudentId id
merge 1:1 id using `points', nogen
gen peers = PeerPoints / CountPeers
li id points peers
+------------------------+
| id points peers |
|------------------------|
1. | 1 45 11 |
2. | 2 42 42.5 |
3. | 3 25 26.5 |
4. | 4 60 26.5 |
5. | 5 11 43.33333
+------------------------+
在上面的代码中,我reshape
将您的对等数据转换为长格式数据并仅保留学生 - 对等对。然后,我将这些数据合并到积分数据中,以获得每个同学的积分。从这里开始,我collapse
将数据返回到学生级别,总计同级点和过程中的对等点数。此时,您可以获得每个学生的同学的总积分以及每个学生的同龄人数。现在,您只需merge
返回积分数据即可获得学生积分并将总同伴积分(PeerPoints
)除以学生所拥有的同伴人数(CountPeers
)平均同行点数。
答案 1 :(得分:2)
nwcommands
是一个我从未使用过或研究过的优秀软件包,所以我将从第一原则尝试这个问题。这是所有矩阵代数,但是给定矩阵和变量,我会在Stata中像这样接近它。
clear
scalar third = 1/3
mat M = (0,0,0,0,1\0,0,0.5,0.5,0\0,0.5,0,0,0.5\0,0.5,0,0,0.5\third,0,third,third,0)
input ID Points Peers
1 45 11
2 42 33.5
3 25 26.5
4 60 26.5
5 11 43.33
end
gen Wanted = 0
quietly forval i = 1/5 {
forval j = 1/5 {
replace Wanted = Wanted + M[`i', `j'] * Points[`j'] in `i'
}
}
list
+--------------------------------+
| ID Points Peers Wanted |
|--------------------------------|
1. | 1 45 11 11 |
2. | 2 42 33.5 42.5 |
3. | 3 25 26.5 26.5 |
4. | 4 60 26.5 26.5 |
5. | 5 11 43.33 43.33334 |
+--------------------------------+
小点:使用0.33表示1/3并不能提供足够的精度。例如,对于1/6和1/7,你会遇到类似的问题。
另外,我得知2的同龄人是3和4所以他们的平均值是(25 + 60)/ 2 = 42.5,而不是33.5。
编辑:类似的方法从数据结构开始,非常类似于@ ander2ed
所想象的clear
input int(id points id1 id2 id3 id4 id5)
1 45 0 0 0 0 1
2 42 0 0 1 1 0
3 25 0 1 0 0 1
4 60 0 1 0 0 1
5 11 1 0 1 1 0
end
gen wanted = 0
quietly forval i = 1/5 {
forval j = 1/5 {
replace wanted = wanted + id`j'[`i'] * points[`j'] in `i'
}
}
egen count = rowtotal(id1-id5)
replace wanted = wanted/count
list
+--------------------------------------------------------------+
| id points id1 id2 id3 id4 id5 wanted count |
|--------------------------------------------------------------|
1. | 1 45 0 0 0 0 1 11 1 |
2. | 2 42 0 0 1 1 0 42.5 2 |
3. | 3 25 0 1 0 0 1 26.5 2 |
4. | 4 60 0 1 0 0 1 26.5 2 |
5. | 5 11 1 0 1 1 0 43.33333 3 |
+--------------------------------------------------------------+