我必须将数据帧的列与来自另一个矩阵的指定单元格值相乘。根据定义,这将意味着数据帧的列数等于矩阵中的元素数。
例如,
我有一个像这样的矩阵
[,1] [,2]
[1,] 0.9470883 0.90148918
[2,] 0.6953117 0.69216633
和一个看起来像这样的数据框
id val1 val2 val3 val4
1 1 1 1 3 5
2 2 2 1 3 5
3 3 1 1 4 5
4 4 2 1 4 5
5 5 1 1 3 6
6 6 2 1 3 6
7 7 1 1 4 6
8 8 2 1 4 6
矩阵的每个单元必须乘以相应的数据帧列。可以以行/列方式读取矩阵。这样做(按行),字段将乘以
df$val1 <- df$val1*mat[1,1] #mat[1,1] is 0.9470883
df$val2 <- df$val2*mat[1,2] #mat[1,2] is 0.90148918
df$val3 <- df$val3*mat[2,1] #mat[2,1] is 0.6953117
df$val4 <- df$val4*mat[2,2] #mat[2,2] is 0.69216633
这样输出就是
id val1 val2 val3 val4
1 1 0.9470883 0.9014892 2.085935 3.460832
2 2 1.8941766 0.9014892 2.085935 3.460832
3 3 0.9470883 0.9014892 2.781247 3.460832
4 4 1.8941766 0.9014892 2.781247 3.460832
5 5 0.9470883 0.9014892 2.085935 4.152998
6 6 1.8941766 0.9014892 2.085935 4.152998
7 7 0.9470883 0.9014892 2.781247 4.152998
8 8 1.8941766 0.9014892 2.781247 4.152998
我希望在矩阵和数据框架的更大尺寸上执行此操作,其速度比for循环更快。
答案 0 :(得分:2)
执行此操作的方法(没有列id
)是:
mapply('*', df, c(mat))
最终转换为dataframe:
as.data.frame(mapply('*', df, c(mat)))
示例:
as.data.frame(mapply('*', cars, c(100, 1000)))
关于专栏id
,您可以稍微改变一下:
my.cars <- cbind(id=1:nrow(cars), cars)
cbind(my.cars[1], as.data.frame(mapply('*', my.cars[-1], c(100, 1000))))
所以在你的情况下:
cbind(df[1], as.data.frame(mapply('*', df[-1], c(mat))))
答案 1 :(得分:2)
df <- read.table( header=TRUE,
text = "id val1 val2 val3 val4
1 1 1 3 5
2 2 1 3 5
3 1 1 4 5
4 2 1 4 5
5 1 1 3 6
6 2 1 3 6
7 1 1 4 6
8 2 1 4 6")
M <- matrix( c(0.9470883,0.90148918,0.6953117,0.69216633), byrow=TRUE )
df[,-1] <- t( t(as.matrix(df[,-1])) * rep(t(M),nrow(df)) )
> df
id val1 val2 val3 val4
1 1 0.9470883 0.9014892 2.085935 3.460832
2 2 1.8941766 0.9014892 2.085935 3.460832
3 3 0.9470883 0.9014892 2.781247 3.460832
4 4 1.8941766 0.9014892 2.781247 3.460832
5 5 0.9470883 0.9014892 2.085935 4.152998
6 6 1.8941766 0.9014892 2.085935 4.152998
7 7 0.9470883 0.9014892 2.781247 4.152998
8 8 1.8941766 0.9014892 2.781247 4.152998
>
答案 2 :(得分:1)
我们也可以使用sweep
df[-1] <- sweep(df[-1], MARGIN=2, c(t(mat)), '*')
df
# id val1 val2 val3 val4
#1 1 0.9470883 0.9014898 2.085935 3.460832
#2 2 1.8941766 0.9014898 2.085935 3.460832
#3 3 0.9470883 0.9014898 2.781247 3.460832
#4 4 1.8941766 0.9014898 2.781247 3.460832
#5 5 0.9470883 0.9014898 2.085935 4.152998
#6 6 1.8941766 0.9014898 2.085935 4.152998
#7 7 0.9470883 0.9014898 2.781247 4.152998
#8 8 1.8941766 0.9014898 2.781247 4.152998