有没有办法用应用语句修改 data.frame 中的特定单元格?

Is there a way to modify specific cells in a data.frame with an apply-statement?

我有一个数据集

   V1  V2  V3  V4
1 0.2 0.1 0.0 0.8
2 0.3 0.4 0.3 0.0
3 0.1 0.3 0.2 0.0
4 0.2 0.1 0.4 0.1
5 0.2 0.1 0.1 0.1

其中每个变量都有一个单元格,我想在其中添加同一列中其他值的一小部分 (10%)。

这表示每个变量中应获得奖励的行:

bonus<-c(2,3,1,4) 

所需的输出是这样的:

   V1   V2   V3   V4
1 0.18 0.09 0.10 0.72
2 0.37 0.36 0.27 0.00
3 0.09 0.37 0.18 0.00
4 0.18 0.09 0.36 0.19
5 0.18 0.09 0.09 0.09

我用 for-loop 做这个:

for(i in 1:ncol(tab)){
  tab[bonus[i],i]<-tab[bonus[i],i]+sum(0.1*tab[-bonus[i],i])
  tab[-bonus[i],i]<-tab[-bonus[i],i]-(0.1*tab[-bonus[i],i])
}

{} 中的第一行将 0.1*sum_of_other_values 添加到索引在 bonus 中的所需单元格,第二行从除 bonus 中的单元格之外的所有单元格中减去。

但我需要对很多矩阵中的很多列执行此操作,并且正在努力将来自外部向量 bonus 的信息包含到无循环函数中。

有没有办法对其进行矢量化,然后 apply 跨数据集使其更快?

非常感谢!

( 示例数据:

tab<-data.frame(V1=c(0.2,0.3,0.1,0.2,0.2),
                V2=c(0.1,0.4,0.3,0.1,0.1),
                V3=c(0.00,0.3,0.2,0.4,0.1),
                V4=c(0.8,0.0,0.0,0.1,0.1))

)

试试这个:

mapply(
  function(vec, bon) { 
    more <- vec/10
    vec + ifelse(seq_along(vec) %in% bon, sum(more[-bon]), -more)
  }, asplit(tab, 2), bonus)
#        V1   V2   V3   V4
# [1,] 0.18 0.09 0.10 0.72
# [2,] 0.37 0.36 0.27 0.00
# [3,] 0.09 0.37 0.18 0.00
# [4,] 0.18 0.09 0.36 0.19
# [5,] 0.18 0.09 0.09 0.09

有时我会尝试将 change 从函数中分离出来(例如当您想在更新原始 tab乐);如果有吸引力,那么可以稍微改变一下:

changes <- mapply(
  function(vec, bon) {
    more <- vec/10
    ifelse(seq_along(vec) %in% bon, sum(more[-bon]), -more)
  }, asplit(tab, 2), bonus)
changes
#         V1    V2    V3    V4
# [1,] -0.02 -0.01  0.10 -0.08
# [2,]  0.07 -0.04 -0.03  0.00
# [3,] -0.01  0.07 -0.02  0.00
# [4,] -0.02 -0.01 -0.04  0.09
# [5,] -0.02 -0.01 -0.01 -0.01
tab + changes
#     V1   V2   V3   V4
# 1 0.18 0.09 0.10 0.72
# 2 0.37 0.36 0.27 0.00
# 3 0.09 0.37 0.18 0.00
# 4 0.18 0.09 0.36 0.19
# 5 0.18 0.09 0.09 0.09