使用输入列

时间:2016-11-04 22:26:14

标签: r dataframe multiplying

我想将某些data.frame * df1 * 中的多列与 * df1 * <中匹配 * df1 * <列中标题的百分比相乘/ strong>即可。这些在data.frame df2 ,第1列中提供,名为 ID 。我希望输出与 df3 中的输出相同。

请注意,我的数据集很大。 df1 中有13.000行和33列。 df2 中有136行和3列。

处理此问题的最佳方法是什么?

df1,df2,df3 的示例如下。

DF1

&#13;
&#13;
Date                  V1               V2            V3            V4
1/1/2000               0               0.4           0             0
2/1/2000               0               0.1           0             0.1
3/1/2000               0.5             0             0             1
4/2000                 0.8             1.5           1             1
&#13;
&#13;
&#13;

DF2

&#13;
&#13;
    ID                Subbasin       Percentage
V1                 001               0.4
V4                 001               0.6
V1                 002               0.2
V2                 002               0.8
V1                 003               0.1
V2                 003               0.3
V3                 003               0.2
V4                 003               0.4
&#13;
&#13;
&#13;

DF3

&#13;
&#13;
Date                   001             002             003
1/1/2000               0               0.32            0.12
2/1/2000               0.06            0.08            0.07
3/1/2000               0.8             0.1             0.45
4/2000                 0.92            1.36            1.13
&#13;
&#13;
&#13;

我想我必须先用

省略日期
df1 <- NULL

3 个答案:

答案 0 :(得分:0)

在对第二个data.frame进行一点重塑之后,您可以使用稀疏矩阵来执行此矩阵乘法:

library(dplyr); library(Matrix); library(reshape2)
m1 <- df1 %>% select(-Date) %>% as.matrix
m2 <- dcast(df2, ID~subbasin, fill=0) %>% select(-ID) %>% as.matrix %>%  Matrix(sparse=T)
m1 %*% m2
#### 4 x 3 Matrix of class "dgeMatrix"
####         1    2    3
#### [1,] 0.00 0.32 0.12
#### [2,] 0.06 0.08 0.07
#### [3,] 0.80 0.10 0.45
#### [4,] 0.92 1.36 1.13

如果df2没有任何零,则此方法有效。如果是的话,你必须添加一些技巧来使稀疏性正确。

我使用了这个重新创建的数据:

df1 = data.frame(Date=c("1/1/2000", "1/2/2000", "1/3/2000", "1/4/2000"), 
                 V1=c(0, 0, .5, .8),
                 V2=c(.4,.1,0, 1.5),
                 V3=c(0,0,0,1),
                 V4=c(0, .1, 1, 1))
df2=data.frame(ID=c("V1", "V4", "V1", "V2", "V1", "V2", "V3", "V4"), 
               subbasin=as.character(c(1,1,2,2,3,3,3,3)),
               percentage=c(4, 6, 2, 8, 1, 3, 2, 4)/10)

答案 1 :(得分:0)

考虑使用您转换两次的reshape2包:1)melt(从宽到长); 2)merge(df1和df2)与产品领域; 3)dcast(长到宽):

library(reshape2)

df1 <- read.table(text="Date V1 V2  V3 V4
1/1/2000 0 0.4 0 0
2/1/2000 0 0.1 0 0.1
3/1/2000 0.5 0 0 1
4/2000 0.8 1.5 1 1", 
 header=TRUE, stringsAsFactors = FALSE)

df2 <- read.table(text="ID Subbasin Percentage
V1 001 0.4
V4 001 0.6
V1 002 0.2
V2 002 0.8
V1 003 0.1
V2 003 0.3
V3 003 0.2
V4 003 0.4", 
  header=TRUE, colClasses=c("character", "character", "numeric"))

df1 <- melt(df1, id.vars=c("Date"), variable.name="ID")

df3 <- merge(df1, df2, by=c("ID"))
df3$product <- df3$value * df3$Percentage

df3 <- dcast(df3, Date~Subbasin, fun.aggregate=sum, value.var="product")
df3
#         Date    001    002    003
# 1   1/1/2000   0.00   0.32   0.12
# 2   2/1/2000   0.06   0.08   0.07
# 3   3/1/2000   0.80   0.10   0.45
# 4     4/2000   0.92   1.36   1.13

答案 2 :(得分:0)

以下是使用base R

的其他选项
df3 <- df1[-4]
df3[ -1] <- as.matrix(df1[-1]) %*% xtabs(Percentage~ ID + Subbasin, df2)
df3
#      Date   V1   V2   V4
#1 1/1/2000 0.00 0.32 0.12
#2 2/1/2000 0.06 0.08 0.07
#3 3/1/2000 0.80 0.10 0.45
#4   4/2000 0.92 1.36 1.13