将列中的值乘以其他列

时间:2014-12-12 07:50:43

标签: r

我是R.的新手 我想要乘以数据帧列。这类问题必须非常基础,但我是R.的新手。我输入数据为

Id  Name    quantity
Id1 Name1   200
Id2 Name2   300
Id3 Name3   500
Id4 Name4   400


Name    BonusMultiplier
Name1       1
Name2       2
Name3       3
Name4       2

Date        Name1   Name2   Name3   Name4
12/3/2014   20.5    200.3   56.3    550.6   
12/2/2014   21.5    180.3   60.5    556.2
12/1/2014   19.6    190.0   61.6    559.6
11/30/2014  15.6    195.6   62.6    580.8

我想要的输出应该像

Date        Name1       Name2           Name3       Name4
12/3/2014   20.5*200*1  200.3*300*2     56.3*500*3  550.6*400*2
12/2/2014   21.5*200*1  180.3*300*2     60.5*500*3  556.2*400*2
12/1/2014   19.6*200*1  190.0*300*2     61.6*500*3  559.6*400*2
11/30/2014  15.6*200*1  195.6*300*2     62.6*500*3  580.8*400*2

修改

如果输出

怎么办?
Date        Id1          Id2            Id3          Id4
12/3/2014   20.5*200*1  200.3*300*2     56.3*500*3  550.6*400*2
12/2/2014   21.5*200*1  180.3*300*2     60.5*500*3  556.2*400*2
12/1/2014   19.6*200*1  190.0*300*2     61.6*500*3  559.6*400*2
11/30/2014  15.6*200*1  195.6*300*2     62.6*500*3  580.8*400*2

3 个答案:

答案 0 :(得分:3)

您可以尝试Map(假设数据集已订购)

df3[,-1] <- Map(function(x,y,z) x*y*z, 
          df3[,-1], df2$BonusMultiplier, df1$quantity)

df3
#        Date Name1  Name2 Name3  Name4
#1  12/3/2014  4100 120180 84450 440480
#2  12/2/2014  4300 108180 90750 444960
#3  12/1/2014  3920 114000 92400 447680
#4 11/30/2014  3120 117360 93900 464640

使用merge将第三个数据集转换为Reduce格式后,另一个选项是long(使用melt)数据集,然后创建mutliplied使用transform的列,最后使用longwide表单转换为dcast格式。

library(reshape2)
lst <- list(setNames(melt(df3, id.var='Date'), 
                c('Date', 'Name', 'value')), df1, df2)

 dcast(
      transform(
         Reduce(function(...) merge(..., by='Name'), lst),
           value=value*quantity*BonusMultiplier)[,1:3],
                          Date~Name, value.var='value')

数据

df1 <- tructure(list(Id = 1:4, Name = c("Name1", "Name2", "Name3", 
"Name4"), quantity = c(200L, 300L, 500L, 400L)), .Names = c("Id", 
"Name", "quantity"), class = "data.frame", row.names = c(NA, -4L))

df2 <- structure(list(Name = c("Name1", "Name2", "Name3", "Name4"), 
BonusMultiplier = c(1L, 2L, 3L, 2L)), .Names = c("Name", 
"BonusMultiplier"), class = "data.frame", row.names = c(NA, -4L))

df3 <- structure(list(Date = c("12/3/2014", "12/2/2014", "12/1/2014", 
"11/30/2014"), Name1 = c(20.5, 21.5, 19.6, 15.6), Name2 = c(200.3, 
180.3, 190, 195.6), Name3 = c(56.3, 60.5, 61.6, 62.6), Name4 = c(550.6, 
556.2, 559.6, 580.8)), .Names = c("Date", "Name1", "Name2", "Name3", 
"Name4"), class = "data.frame", row.names = c(NA, -4L))

答案 1 :(得分:1)

我的版本。

require(reshape2)

#create data
m1 <- data.frame(Id=paste0("Id", seq(1,4)), Name=paste0("Name", seq(1,4)),
quantity=c(2, 3, 5, 4)*100)
m2 <- data.frame(Name=paste0("Name", seq(1,4)), BonusMultiplier=c(1, 2, 3, 2))
m3 <- data.frame(rbind(c("12/3/2014", 20.5, 200.3, 56.3, 550.6),
                       c("12/2/2014", 21.5, 180.3, 60.5, 556.2),
                       c("12/1/2014", 19.6, 190.0, 61.6, 559.6),
                       c("11/30/2014", 15.6, 195.6, 62.6, 580.8)))
names(m3) <- c("Date", "Name1", "Name2", "Name3", "Name4")

#do the work
m.melt <- melt(m3, id.vars="Date", variable.name="Name", value.name="Value")
m.all <- merge(merge(m.melt, m1), m2)
m.all <- within(m.all,
                answer <- paste(Value, quantity, BonusMultiplier, sep="*"))

dcast(m.all, Date ~ Name)

下面的输出
Date      Name1       Name2      Name3       Name4
1 11/30/2014 15.6*200*1 195.6*300*2 62.6*500*3 580.8*400*2
2  12/1/2014 19.6*200*1   190*300*2 61.6*500*3 559.6*400*2
3  12/2/2014 21.5*200*1 180.3*300*2 60.5*500*3 556.2*400*2
4  12/3/2014 20.5*200*1 200.3*300*2 56.3*500*3 550.6*400*2

答案 2 :(得分:0)

#Here is a simple solution:
# Step 1: sort the three data frames according to 'Name'.
df1.1 <- df1[order(df1$Name), ]
df2.1 <- df2[order(df2$Name), ]
df3.1 <- df3[, c("Date", order(names(df3)[-1]))]

# Step 2: define a new data.frame named df3.2 to store the output
df3.2 <- data.frame(matrix(NA, ncol=ncol(df3.1), nrow=nrow(df3.1)))
df3.2[, 1] <- df3.1[, 1]
names(df3.2) <- names(df3.1)

# Step 3. run a for-loop to calculate for each column of df3.1
for(i in 1:(ncol(df3.1)-1))
{
   j <- i+1
   df3.2[, j] <- df3.1[, j] * df1.1[i, "quantity"] * df2.1[i, "BonusMultiplier"]
}

head(df3.2)