如何使用R中的查找方法基于其他列计算新列?

时间:2019-04-23 02:42:02

标签: r dataframe lookup-tables

我正在尝试根据其他列和查找表来计算数据框中的另一列。我有一个简单的示例,该示例仅显示很少的数据(我的真实数据集包含数百万行)。

我有以下数据集:

  lookup<- data.frame("class"=c(1, 2, 1, 2), "type"=c("A", "B", "B", "A"), 
           "condition1"=c(50, 60, 55, 53), "condition2"=c(80, 85, 86, 83))

  lookup
  class type condition1 condition2
      1    A         50         80
      2    B         60         85
      1    B         55         86
      2    A         53         83

我的数据框具有以下形状:

  data<- data.frame("class"=c(1, 2, 2, 1, 2, 1), 
         "type"=c("A","B", "A", "A", "B", "B"), 
         "percentage_condition1"=c(0.3, 0.6, 0.1, 0.2, 0.4, 0.5), 
         "percentage_condition2"=c(0.7, 0.4, 0.9, 0.8, 0.6, 0.5))


  data
  class type percentage_condition1 percentage_condition2
    1    A                   0.3                   0.7
    2    B                   0.6                   0.4
    2    A                   0.1                   0.9
    1    A                   0.2                   0.8
    2    B                   0.4                   0.6
    1    B                   0.5                   0.5

我想在我的数据框中创建一个名为data的新列,该列将使用查找表,例如:

在我的 class 与我的 type 列匹配的数据中,它可以计算数据框数据中的新列,例如(不是真实代码):

d $ new <-查找$ condition1 *数据$ percentage_condition1 +查找$ condition2 *数据$ percentage_condition2

我知道如何使用if else语句来执行此操作,但是由于要处理大量数据,因此我试图更有效地执行操作。我知道要用查找表中的一列来完成此操作,但不能成功使用几列(类和类型列)。

感谢您的帮助和建议!

2 个答案:

答案 0 :(得分:2)

我们可以使用doesObjectExist来获取'data'和'type'的'type'列的索引,使用该索引来获取'condition1','condition2'列的对应行,并乘以百分比列中的“数据”并获取match

rowSums

注意:使用data$new <- rowSums(lookup[match(paste(data$class, data$type), paste(lookup$class, lookup$type)), c("condition1", "condition2")] * data[3:4]) data # class type percentage_condition1 percentage_condition2 new #1 1 A 0.3 0.7 71.0 #2 2 B 0.6 0.4 70.0 #3 2 A 0.1 0.9 80.0 #4 1 A 0.2 0.8 74.0 #5 2 B 0.4 0.6 75.0 #6 1 B 0.5 0.5 70.5 ,我们可以更轻松地完成


或使用match

data.table

或使用library(data.table) setDT(data)[lookup, new := condition1 * percentage_condition1 + condition2 * percentage_condition2, on = .(class, type)] data # class type percentage_condition1 percentage_condition2 new #1: 1 A 0.3 0.7 71.0 #2: 2 B 0.6 0.4 70.0 #3: 2 A 0.1 0.9 80.0 #4: 1 A 0.2 0.8 74.0 #5: 2 B 0.4 0.6 75.0 #6: 1 B 0.5 0.5 70.5

tidyverse

或将基于SQL的解决方案与library(tidyverse) data %>% left_join(lookup, by = c("class", "type")) %>% mutate(new = condition1 * percentage_condition1 + condition2 * percentage_condition2) %>% select(names(data), new) # class type percentage_condition1 percentage_condition2 new #1 1 A 0.3 0.7 71.0 #2 2 B 0.6 0.4 70.0 #3 2 A 0.1 0.9 80.0 #4 1 A 0.2 0.8 74.0 #5 2 B 0.4 0.6 75.0 #6 1 B 0.5 0.5 70.5

一起使用
sqldf

或者就像评论中提到的@ G.Grothendieck一样,使用别名标识符,library(sqldf) str1 <- "SELECT data.class, data.type, data.percentage_condition1, data.percentage_condition2, (data.percentage_condition1 * lookup.condition1 + data.percentage_condition2 * lookup.condition2) as new FROM data LEFT JOIN lookup on data.class = lookup.class AND data.type = lookup.type" sqldf(str1) 解决方案可以变得更紧凑

sqldf

注意:所有解决方案均保持数据集的原始顺序

答案 1 :(得分:2)

一个选择是doPost(e) mergedata然后执行计算

lookup