【问题标题】:multiply two different data.frames to a new data.frame with new columnheaders from input column将两个不同的 data.frame 与输入列中的新列标题相乘到一个新的 data.frame
【发布时间】:2017-03-18 20:54:34
【问题描述】:

我想将某个 data.frame * df1* 中的几列与 Percentages 相乘以匹配 * df1*。这些在 data.frame df2 第 1 列中给出,称为 ID。我希望输出与 df3 中的一样。

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

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

df1、df2、df3的示例如下。

df1

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

df2

    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

df3

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

我想我必须从省略 日期 开始,用

df1 <- NULL

【问题讨论】:

  • 您好,如果有任何答案解决了您的问题,您可以点击“接受”以便其他人看到吗?谢谢

标签: r dataframe multiplication


【解决方案1】:

考虑使用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】:

    你可以使用稀疏矩阵来做这个矩阵乘法,在对第二个 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)
    

    【讨论】:

      【解决方案3】:

      这是另一个使用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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-27
        • 2021-09-04
        • 1970-01-01
        相关资源
        最近更新 更多