我有以下示例数据。有三个组X、Y和Z,观察结果1到9被分为这些组。对于每个观察,我观察变量A和B。因此:
test <- data.frame(
id = 1:9,
group = c(rep("X", 3), rep("Y", 3), rep("Z", 3)),
A = seq(from = 0.15, to = 0.55, by = 0.05),
B = 5:13
)
这就产生了
id group A B
1 1 X 0.15 5
2 2 X 0.20 6
3 3 X 0.25 7
4 4 Y 0.30 8
5 5 Y 0.35 9
6 6 Y 0.40 10
7 7 Z 0.45 11
8 8 Z 0.50 12
9 9 Z 0.55 13
我很长一段时间以来一直试图实现的是:对于每个观测值1到9,求和该观测值a相对于该观测值组所有其他观测值a的加权差。因此,对于观测1到4(作为示例),它应该是这样的:
id 1: (0.15 - 0.15) * 5 + (0.15 - 0.20) * 6 + (0.15 - 0.25) * 7 = -1
id 2: (0.20 - 0.15) * 5 + (0.20 - 0.20) * 6 + (0.20 - 0.25) * 7 = -0.1
id 3: (0.25 - 0.15) * 5 + (0.25 - 0.20) * 6 + (0.25 - 0.25) * 7 = 0.8
id 4: (0.30 - 0.30) * 8 + (0.30 - 0.35) * 9 + (0.30 - 0.40) * 10 = -1.45
例如,对于观察3,这转化为单词:
步骤1:0.25是观察3在A上的值,将该值与观察1在A上(为0.15)的值进行比较,0.10的差值乘以5(观察1在B上的值)
步骤2:0.25(A上观察3的值)与A上观察2的值(0.20)进行比较,0.05的差异由6(B上观察2值)加权
步骤3:0.25(观察3在A上的值)与A上的(它自己的)值进行比较,将0的差值乘以7(它在B上的自己的值)(我认为,考虑到0的差值,这一步骤是不必要的;它是为了完整性而添加的)。
步骤4:步骤1-3 的总和
有没有可行的方法在R中实现这一点?我一直在尝试使用mutate
和group_by
,但到目前为止都没有成功。非常感谢您的帮助。
您可以使用group_by()
和一点线性代数:
library(dplyr)
test <- data.frame(
id = 1:9,
group = c(rep("X", 3), rep("Y", 3), rep("Z", 3)),
A = seq(from = 0.15, to = 0.55, by = 0.05),
B = 5:13
)
test %>% group_by(group) %>%
mutate(res = A*sum(B) - c(A%*%B))
#> # A tibble: 9 x 5
#> # Groups: group [3]
#> id group A B res
#> <int> <fct> <dbl> <int> <dbl>
#> 1 1 X 0.15 5 -1.
#> 2 2 X 0.2 6 -0.1
#> 3 3 X 0.25 7 0.800
#> 4 4 Y 0.3 8 -1.45
#> 5 5 Y 0.35 9 -0.1
#> 6 6 Y 0.4 10 1.25
#> 7 7 Z 0.45 11 -1.90
#> 8 8 Z 0.5 12 -0.1
#> 9 9 Z 0.55 13 1.70
创建于2019-01-21由reprex包(v0.2.1)
您可以尝试使用data.table
:
> test[, out := colSums(sapply(A, function(x) (x - A) * B)), by = "group"]
> test
id group A B out
1: 1 X 0.15 5 -1.00
2: 2 X 0.20 6 -0.10
3: 3 X 0.25 7 0.80
4: 4 Y 0.30 8 -1.45
5: 5 Y 0.35 9 -0.10
6: 6 Y 0.40 10 1.25
7: 7 Z 0.45 11 -1.90
8: 8 Z 0.50 12 -0.10
9: 9 Z 0.55 13 1.70
我所做的是:我将自定义函数function(x) (x - A) * B)
应用于列A
的每个元素,这给了我一个(A[i] - A[j]) * B[j]
元素的矩阵。然后我对列求和,得到结果向量。