观察结果相对于一组中所有其他观察结果的加权差异(R)



我有以下示例数据。有三个组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中实现这一点?我一直在尝试使用mutategroup_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]元素的矩阵。然后我对列求和,得到结果向量。

最新更新