умножьте два разных data.frames на новый data.frame с новыми заголовками столбцов из входного столбца

Я хотел бы умножить несколько столбцов из определенного кадра data.frame * df1 * на проценты, соответствующие заголовкам столбцов в * 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

person T. BruceLee    schedule 04.11.2016    source источник
comment
Привет, если какой-либо ответ решит вашу проблему, можете ли вы нажать на "Принять его", чтобы другие люди могли его увидеть? Благодарность   -  person agenis    schedule 06.09.2017


Ответы (3)


Рассмотрите возможность использования пакета 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
person Parfait    schedule 04.11.2016

Вы можете использовать Sparse Matrix для этого умножения матриц после небольшого изменения формы второго 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)
person agenis    schedule 04.11.2016

Вот еще один вариант с использованием 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
person akrun    schedule 05.11.2016