与多个条件匹配,在 R 中没有循环
Match with multiple criteria without loop in R
我有一个显示一组条件的数据框,例如:
B = data.frame(col1 = 1:10, col2 = 11:20 )
例如,第一行表示当 col1 = 1 时,col2 = 11。
我还有另一个数据框,其中包含应满足这些条件的数字,例如:
A = data.frame(col1 = c(1:11,1:11), col2 = c(11:21,11:21), col3 = 101:122)
我想 return 矩阵 A
中 col3
中满足 B 中条件的所有行的值的总和。例如,使用中的第一行B 这个值为:
sum(A$col3[which(A$col1 == B$col1[1] & A$col2 == B$col2[1])])
#[1] 213
即A
第1行和第12行col3
项之和。我需要为矩阵 A
的所有行找到一个包含所有这些总和的向量。我知道如何用循环来做到这一点,但是在我的数据矩阵中 A
和 B
非常大并且有很多条件,所以我想知道是否有一种方法可以在没有环形。谢谢。
使用 dplyr
的解决方案。 A2
是最终输出。这个想法是将 col1
和 col2
中的值分组并计算 col3
的总和。 semi_join
是在B
.
中根据col1
和col2
匹配值过滤数据框
library(dplyr)
A2 <- A %>%
group_by(col1, col2) %>%
summarise(col3 = sum(col3)) %>%
semi_join(B, by = c("col1", "col2")) %>%
ungroup()
A2
# # A tibble: 10 x 3
# col1 col2 col3
# <int> <int> <int>
# 1 1 11 213
# 2 2 12 215
# 3 3 13 217
# 4 4 14 219
# 5 5 15 221
# 6 6 16 223
# 7 7 17 225
# 8 8 18 227
# 9 9 19 229
# 10 10 20 231
我们可以使用 data.table
进行联接 on
library(data.table(
setDT(A)[B, .(col3 = sum(col3)), on = .(col1, col2), by = .EACHI]
# col1 col2 col3
# 1: 1 11 213
# 2: 2 12 215
# 3: 3 13 217
# 4: 4 14 219
# 5: 5 15 221
# 6: 6 16 223
# 7: 7 17 225
# 8: 8 18 227
# 9: 9 19 229
#10: 10 20 231
基于 R 的解决方案
# Sum identical rows
A.summed <- aggregate(col3 ~ col1 + col2, data = A, sum);
# Select col1 col2 combinations that are also present in B
A.summed.sub <- subset(A.summed, paste(col1, col2) %in% paste(B$col1, B$col2));
# col1 col2 col3
#1 1 11 213
#2 2 12 215
#3 3 13 217
#4 4 14 219
#5 5 15 221
#6 6 16 223
#7 7 17 225
#8 8 18 227
#9 9 19 229
#10 10 20 231
或与单线相同
A.summed.sub <- subset(aggregate(col3 ~ col1 + col2, data = A, sum), paste(col1, col2) %in% paste(B$col1, B$col2));
# Add summed col3 to dataframe B by matching col1 col2 combinations
B$col3 <- A.summed[match(paste(B$col1, B$col2), paste(A.summed$col1, A.summed$col2)), "col3"];
B;
# col1 col2 col3
#1 1 11 213
#2 2 12 215
#3 3 13 217
#4 4 14 219
#5 5 15 221
#6 6 16 223
#7 7 17 225
#8 8 18 227
#9 9 19 229
#10 10 20 231
我有一个显示一组条件的数据框,例如:
B = data.frame(col1 = 1:10, col2 = 11:20 )
例如,第一行表示当 col1 = 1 时,col2 = 11。 我还有另一个数据框,其中包含应满足这些条件的数字,例如:
A = data.frame(col1 = c(1:11,1:11), col2 = c(11:21,11:21), col3 = 101:122)
我想 return 矩阵 A
中 col3
中满足 B 中条件的所有行的值的总和。例如,使用中的第一行B 这个值为:
sum(A$col3[which(A$col1 == B$col1[1] & A$col2 == B$col2[1])])
#[1] 213
即A
第1行和第12行col3
项之和。我需要为矩阵 A
的所有行找到一个包含所有这些总和的向量。我知道如何用循环来做到这一点,但是在我的数据矩阵中 A
和 B
非常大并且有很多条件,所以我想知道是否有一种方法可以在没有环形。谢谢。
使用 dplyr
的解决方案。 A2
是最终输出。这个想法是将 col1
和 col2
中的值分组并计算 col3
的总和。 semi_join
是在B
.
col1
和col2
匹配值过滤数据框
library(dplyr)
A2 <- A %>%
group_by(col1, col2) %>%
summarise(col3 = sum(col3)) %>%
semi_join(B, by = c("col1", "col2")) %>%
ungroup()
A2
# # A tibble: 10 x 3
# col1 col2 col3
# <int> <int> <int>
# 1 1 11 213
# 2 2 12 215
# 3 3 13 217
# 4 4 14 219
# 5 5 15 221
# 6 6 16 223
# 7 7 17 225
# 8 8 18 227
# 9 9 19 229
# 10 10 20 231
我们可以使用 data.table
on
library(data.table(
setDT(A)[B, .(col3 = sum(col3)), on = .(col1, col2), by = .EACHI]
# col1 col2 col3
# 1: 1 11 213
# 2: 2 12 215
# 3: 3 13 217
# 4: 4 14 219
# 5: 5 15 221
# 6: 6 16 223
# 7: 7 17 225
# 8: 8 18 227
# 9: 9 19 229
#10: 10 20 231
基于 R 的解决方案
# Sum identical rows
A.summed <- aggregate(col3 ~ col1 + col2, data = A, sum);
# Select col1 col2 combinations that are also present in B
A.summed.sub <- subset(A.summed, paste(col1, col2) %in% paste(B$col1, B$col2));
# col1 col2 col3
#1 1 11 213
#2 2 12 215
#3 3 13 217
#4 4 14 219
#5 5 15 221
#6 6 16 223
#7 7 17 225
#8 8 18 227
#9 9 19 229
#10 10 20 231
或与单线相同
A.summed.sub <- subset(aggregate(col3 ~ col1 + col2, data = A, sum), paste(col1, col2) %in% paste(B$col1, B$col2));
# Add summed col3 to dataframe B by matching col1 col2 combinations
B$col3 <- A.summed[match(paste(B$col1, B$col2), paste(A.summed$col1, A.summed$col2)), "col3"];
B;
# col1 col2 col3
#1 1 11 213
#2 2 12 215
#3 3 13 217
#4 4 14 219
#5 5 15 221
#6 6 16 223
#7 7 17 225
#8 8 18 227
#9 9 19 229
#10 10 20 231