r 中组内的高效成对操作
Efficient pair-wise operations within groups in r
我有一个包含公司及其绩效指标以及其他信息的数据集。我想根据该行业所有其他公司(不包括焦点公司)的加权平均绩效为每个公司定义“社会期望水平”。
更具体地说:
其中 i 表示焦点公司,t 表示时间 t。 j表示同行业的其他公司,P是公司规模,I是收入。
对于下面给定的数据集:
set.seed(123)
df = data.table(
"Firm" = c(rep(c("A","B","C","D"),times=2),rep(c("E","F","G","H"),times=2)),
"Year" = c(rep(c(2001,2002),each=4),rep(c(2001,2002),each=4)),
"Income" = sample(100:200,16),
"Size" = sample(1:20,16),
"Industry_Code" = rep(c(100,200),each=8)
)
df
Firm Year Income Size Industry_Code
1: A 2001 130 7 100
2: B 2001 178 10 100
3: C 2001 150 9 100
4: D 2001 113 4 100
5: A 2002 166 14 100
6: B 2002 141 1 100
7: C 2002 149 11 100
8: D 2002 142 20 100
9: E 2001 197 5 200
10: F 2001 124 19 200
11: G 2001 189 13 200
12: H 2001 168 18 200
13: E 2002 156 15 200
14: F 2002 108 2 200
15: G 2002 171 3 200
16: H 2002 125 17 200
期望的结果是:
Firm Year Income Size Industry_Code SA
1: A 2001 130 7 100 40.91667
2: B 2001 178 10 100 41.21429
3: C 2001 150 9 100 50.38889
4: D 2001 113 4 100 27.64286
5: A 2002 166 14 100 22.53571
6: B 2002 141 1 100 10.83420
7: C 2002 149 11 100 12.44329
8: D 2002 142 20 100 15.22143
9: E 2001 197 5 200 13.75556
10: F 2001 124 19 200 41.37778
11: G 2001 189 13 200 22.53439
12: H 2001 168 18 200 35.85714
13: E 2002 156 15 200 20.84493
14: F 2002 108 2 200 34.81845
15: G 2002 171 3 200 24.77778
16: H 2002 125 17 200 23.38333
请注意,例如,对于 2001 年的 A,SA 由 ((178/4+150/3+113/4)/3) 给出。
for 循环会做我想做的事,但它非常慢。
data.table 解决方案更可取,我想通过分组行业和年份来迭代它。
我知道开发解决方案可能很耗时,因此非常感谢您的帮助。
不确定这是否会比您的循环更快,因为 sapply
本质上是一个循环,但这里是使用 data.table 分组的公式的相对简单的实现。
df[, sa := (sapply(Size, function(s) sum(Income/(1 + abs(s - Size)))) - Income)/(.N - 1),
.(Year, Industry_Code)]
df
# Firm Year Income Size Industry_Code sa
# 1: A 2001 130 7 100 40.91667
# 2: B 2001 178 10 100 41.21429
# 3: C 2001 150 9 100 50.38889
# 4: D 2001 113 4 100 27.64286
# 5: A 2002 166 14 100 22.53571
# 6: B 2002 141 1 100 10.83420
# 7: C 2002 149 11 100 22.83939
# 8: D 2002 142 20 100 15.22143
# 9: E 2001 197 5 200 13.75556
# 10: F 2001 124 19 200 41.37778
# 11: G 2001 189 13 200 22.53439
# 12: H 2001 168 18 200 35.85714
# 13: E 2002 156 15 200 20.84493
# 14: F 2002 108 2 200 34.81845
# 15: G 2002 171 3 200 24.77778
# 16: H 2002 125 17 200 23.38333
使用的数据:
df <- fread('
Firm Year Income Size Industry_Code
A 2001 130 7 100
B 2001 178 10 100
C 2001 150 9 100
D 2001 113 4 100
A 2002 166 14 100
B 2002 141 1 100
C 2002 149 11 100
D 2002 142 20 100
E 2001 197 5 200
F 2001 124 19 200
G 2001 189 13 200
H 2001 168 18 200
E 2002 156 15 200
F 2002 108 2 200
G 2002 171 3 200
H 2002 125 17 200
')
我有一个包含公司及其绩效指标以及其他信息的数据集。我想根据该行业所有其他公司(不包括焦点公司)的加权平均绩效为每个公司定义“社会期望水平”。
更具体地说:
其中 i 表示焦点公司,t 表示时间 t。 j表示同行业的其他公司,P是公司规模,I是收入。
对于下面给定的数据集:
set.seed(123)
df = data.table(
"Firm" = c(rep(c("A","B","C","D"),times=2),rep(c("E","F","G","H"),times=2)),
"Year" = c(rep(c(2001,2002),each=4),rep(c(2001,2002),each=4)),
"Income" = sample(100:200,16),
"Size" = sample(1:20,16),
"Industry_Code" = rep(c(100,200),each=8)
)
df
Firm Year Income Size Industry_Code
1: A 2001 130 7 100
2: B 2001 178 10 100
3: C 2001 150 9 100
4: D 2001 113 4 100
5: A 2002 166 14 100
6: B 2002 141 1 100
7: C 2002 149 11 100
8: D 2002 142 20 100
9: E 2001 197 5 200
10: F 2001 124 19 200
11: G 2001 189 13 200
12: H 2001 168 18 200
13: E 2002 156 15 200
14: F 2002 108 2 200
15: G 2002 171 3 200
16: H 2002 125 17 200
期望的结果是:
Firm Year Income Size Industry_Code SA
1: A 2001 130 7 100 40.91667
2: B 2001 178 10 100 41.21429
3: C 2001 150 9 100 50.38889
4: D 2001 113 4 100 27.64286
5: A 2002 166 14 100 22.53571
6: B 2002 141 1 100 10.83420
7: C 2002 149 11 100 12.44329
8: D 2002 142 20 100 15.22143
9: E 2001 197 5 200 13.75556
10: F 2001 124 19 200 41.37778
11: G 2001 189 13 200 22.53439
12: H 2001 168 18 200 35.85714
13: E 2002 156 15 200 20.84493
14: F 2002 108 2 200 34.81845
15: G 2002 171 3 200 24.77778
16: H 2002 125 17 200 23.38333
请注意,例如,对于 2001 年的 A,SA 由 ((178/4+150/3+113/4)/3) 给出。 for 循环会做我想做的事,但它非常慢。 data.table 解决方案更可取,我想通过分组行业和年份来迭代它。
我知道开发解决方案可能很耗时,因此非常感谢您的帮助。
不确定这是否会比您的循环更快,因为 sapply
本质上是一个循环,但这里是使用 data.table 分组的公式的相对简单的实现。
df[, sa := (sapply(Size, function(s) sum(Income/(1 + abs(s - Size)))) - Income)/(.N - 1),
.(Year, Industry_Code)]
df
# Firm Year Income Size Industry_Code sa
# 1: A 2001 130 7 100 40.91667
# 2: B 2001 178 10 100 41.21429
# 3: C 2001 150 9 100 50.38889
# 4: D 2001 113 4 100 27.64286
# 5: A 2002 166 14 100 22.53571
# 6: B 2002 141 1 100 10.83420
# 7: C 2002 149 11 100 22.83939
# 8: D 2002 142 20 100 15.22143
# 9: E 2001 197 5 200 13.75556
# 10: F 2001 124 19 200 41.37778
# 11: G 2001 189 13 200 22.53439
# 12: H 2001 168 18 200 35.85714
# 13: E 2002 156 15 200 20.84493
# 14: F 2002 108 2 200 34.81845
# 15: G 2002 171 3 200 24.77778
# 16: H 2002 125 17 200 23.38333
使用的数据:
df <- fread('
Firm Year Income Size Industry_Code
A 2001 130 7 100
B 2001 178 10 100
C 2001 150 9 100
D 2001 113 4 100
A 2002 166 14 100
B 2002 141 1 100
C 2002 149 11 100
D 2002 142 20 100
E 2001 197 5 200
F 2001 124 19 200
G 2001 189 13 200
H 2001 168 18 200
E 2002 156 15 200
F 2002 108 2 200
G 2002 171 3 200
H 2002 125 17 200
')