我正在尝试根据其他列和查找表来计算数据框中的另一列。我有一个简单的示例,该示例仅显示很少的数据(我的真实数据集包含数百万行)。
我有以下数据集:
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语句来执行此操作,但是由于要处理大量数据,因此我试图更有效地执行操作。我知道要用查找表中的一列来完成此操作,但不能成功使用几列(类和类型列)。
感谢您的帮助和建议!
答案 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)
merge
和data
然后执行计算
lookup