我有两个数据帧A和B。在B中,我有两个键列,对于B中的每一行,我需要计算A中与这些键匹配的行数。
我知道如何使用for循环解决问题,但是这是永远的过程,我想知道是否有更聪明的方法可以做到这一点。我对R还是很陌生,所以如果我错过了一些明显的解决方案,您必须原谅我。
数据帧具有以下结构。当然,实际上数据帧要大得多。
A <- data.frame(c(1, 2, 1), c(2, 1, 2), c("alpha", "bravo", "charlie"))
colnames(A) <- c("key1", "key2", "value")
B <- data.frame(c(1, 2, 3), c(2, 1, 3), NA)
colnames(B) <- c("key1", "key2", "count")
我使用了以下for循环,并获得了正确的结果。
for (i in 1:nrow(B)) {
B$count[i] <- sum(A$key1 == B$key1[i] & A$key2 == B$key2[i], na.rm = TRUE)
}
但是,代码花了相当长的时间才能运行,我怀疑有更好的方法来执行此操作。我将不胜感激!
答案 0 :(得分:4)
base R
中的一个选项(类似于@Sotos tidyverse选项)
aggregate(cbind(count = !is.na(value)) ~ key1 + key2, merge(A, B, all = TRUE), sum)
# key1 key2 count
#1 2 1 1
#2 1 2 2
#3 3 3 0
或与data.table
library(data.table)
setDT(A)[B, .(count = sum(!is.na(value))), on = .(key1, key2), by = .EACHI]
# key1 key2 count
#1: 1 2 2
#2: 2 1 1
#3: 3 3 0
答案 1 :(得分:3)
使用与您相同的逻辑,但不使用mapply
循环
B$count <- mapply(function(x, y)
sum(x == A$key1 & y == A$key2, na.rm = TRUE), B$key1, B$key2)
B
# key1 key2 count
#1 1 2 2
#2 2 1 1
#3 3 3 0
答案 2 :(得分:3)
这里是使用merge
,
library(tidyverse)
A %>%
full_join(B, by = c('key1', 'key2')) %>%
group_by(key1, key2) %>%
summarise(count = sum(!is.na(value)))
给出,
# A tibble: 3 x 3 # Groups: key1 [?] key1 key2 count <dbl> <dbl> <int> 1 1 2 2 2 2 1 1 3 3 3 0
添加data.table
解决方案以完成操作,
library(data.table)
setDT(A)[setDT(B), on = c('key1', 'key2')][,
.(count = sum(!is.na(value))), by = c('key1', 'key2')]
# key1 key2 count
#1: 1 2 2
#2: 2 1 1
#3: 3 3 0