2015-12-19 23 views
0

我必须将数据帧的列乘以另一个矩阵中指定的单元格值。根据定义,这将意味着数据帧的列数等于矩阵中元素的数量。数据框的列与矩阵中各自的单元格值相乘

对于例如

我有这样

  [,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 

我想换比快的东西要做到这一点了矩阵和数据帧的大尺寸循环。

+0

从上面的例子:DF $ VAL1是1的第一个实例。乘以0.9470083时应为0.9470083。你如何得到0.9029538? – MaxPD

+0

啊我的坏,复制时出现了一些错误。更正它。感谢您指出了这一点! – Shikhar

+0

好的。大矩阵的维数是否已知?数据框总是只有4列吗? – MaxPD

回答

2

要做到这一点(不列id)的方式是:

mapply('*', df, c(mat)) 

最终转换成数据帧:

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)))) 
+0

这就是我将要使用的,看起来像在我的大型数据集上工作得更好。谢谢 – Shikhar

+0

因此,最终你想通过点击旁边的投票接受这个答案(或任何其他)。 – jogo

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 
> 
+0

数据框和矩阵的操作非常好。谢谢! – Shikhar

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