基于共享标识符从两个数据帧中乘以值

时间:2018-01-07 04:17:24

标签: r dataframe

我有两个数据框:

第1名:

>df1

 ID NUM QUANT STR IDENT
  1  30    30  10  1111
  1  30    50 100  2222
  2  60    60  20  1111
  3  15    15  10  3333
  3  20    10  10  1111
  4  60    30  20  2222
  5  30    20  15  3333
  6  45    60  10  2222

2号:

>df2

 IDENT FACTOR
  1111    1.0
  2222    0.5
  3333    2.0

我想根据两个数据帧中的值计算一个新值,并将计算出的值附加到数据帧1中名为RESULT的新列中。两个数据帧中的共享标识符为IDENT

用于计算值的公式:

STR*QUANT/NUM*FACTOR=RESULT

最终数据框应如下所示:

  ID NUM QUANT STR IDENT RESULT
  1  30    30  10  1111  10.0000
  1  30    50 100  2222  83.3333
  2  60    60  20  1111  20.0000
  3  15    15  10  3333  20.0000
  3  20    10  10  1111   5.0000
  4  60    30  20  2222   5.0000
  5  30    20  15  3333  20.0000
  6  45    60  10  2222   6.6667

这是用于再现数据帧的代码:

ID = c(1, 1, 2, 3, 3, 4, 5, 6) 
NUM = c(30, 30, 60, 15, 20, 60, 30, 45) 
QUANT = c(30, 50, 60, 15, 10, 30, 20, 60) 
STR = c(10,100,20,10,10,20,15,10)
IDENT = c(1111,2222,1111,3333,1111,2222,3333,2222)
df1 = data.frame(ID, NUM, QUANT, STR, IDENT)   

IDENT = c(1111, 2222, 3333)
FACTOR = c(1, 0.5, 2)
df2 = data.frame(IDENT, FACTOR)

IDENT = c(1111,2222,1111,3333,1111,2222,3333,2222)
RESULT = c(10,83.3333,20,20,5,5,20,6.6667)
df3 = data.frame(ID, NUM, QUANT, STR, IDENT, RESULT) 

3 个答案:

答案 0 :(得分:3)

受上述@ A5C1D2H2I1M1N2O1R2T1评论的启发:

output <- within(merge(df1, df2), { RESULT = STR*QUANT/NUM*FACTOR })
output <- output[, !(names(output) %in% c("FACTOR"))]
output

Demo

答案 1 :(得分:2)

基础R解决方案。我们可以先合并两个数据帧,计算结果,然后最终确定输出。

df3 <- merge(df1, df2, by = "IDENT", all.x = TRUE)
df3$RESULT <- with(df3, STR * QUANT / NUM * FACTOR)
df3 <- df3[, c("ID", "NUM", "QUANT", "STR", "IDENT", "RESULT")]
df3 <- df3[order(df3$ID, df3$NUM), ]
df3
#   ID NUM QUANT STR IDENT    RESULT
# 1  1  30    30  10  1111 10.000000
# 4  1  30    50 100  2222 83.333333
# 2  2  60    60  20  1111 20.000000
# 7  3  15    15  10  3333 20.000000
# 3  3  20    10  10  1111  5.000000
# 5  4  60    30  20  2222  5.000000
# 8  5  30    20  15  3333 20.000000
# 6  6  45    60  10  2222  6.666667

或具有相同逻辑的dplyr解决方案。

library(dplyr)

df3 <- df1 %>%
  left_join(df2, by = "IDENT") %>%
  mutate(RESULT = STR * QUANT / NUM * FACTOR) %>%
  select(-FACTOR) %>%
  arrange(ID, NUM)
df3
#   ID NUM QUANT STR IDENT    RESULT
# 1  1  30    30  10  1111 10.000000
# 4  1  30    50 100  2222 83.333333
# 2  2  60    60  20  1111 20.000000
# 7  3  15    15  10  3333 20.000000
# 3  3  20    10  10  1111  5.000000
# 5  4  60    30  20  2222  5.000000
# 8  5  30    20  15  3333 20.000000
# 6  6  45    60  10  2222  6.666667 

答案 2 :(得分:2)

我们也可以与data.table

进行联接
library(data.table)
setDT(df1)[df2, RESULT := STR*QUANT/NUM*FACTOR, on = .(IDENT)]
df1
#   ID NUM QUANT STR IDENT    RESULT
#1:  1  30    30  10  1111 10.000000
#2:  1  30    50 100  2222 83.333333
#3:  2  60    60  20  1111 20.000000
#4:  3  15    15  10  3333 20.000000
#5:  3  20    10  10  1111  5.000000
#6:  4  60    30  20  2222  5.000000
#7:  5  30    20  15  3333 20.000000
#8:  6  45    60  10  2222  6.666667