我需要找到新向量 (vb) 中的哪些元素已添加到另一个向量 (va)。例如,如果va中只有一个“2”,而vb中只有两个“2”,则添加了一个“2”。
下面代码中的注释显示了所寻求的内容。
va <- c(1, 2) # Original vector
vb <- c(1, 2) # NA or NULL
vb <- c(2, 2) # 2
vb <- c(1, 1) # 1
vb <- c(1) # NA or NULL
vb <- c(2) # NA or NULL
vb <- c(3, 3) # c(3, 3)
我尝试过匹配、并集、相交、%in% 等,但无法让它同时考虑多个实例。这感觉简单得令人恼火......
最佳答案
以下内容再现了您的预期结果。正如一个诚实的提示,我对我的解决方案并不满意,这似乎很奇怪:
f <- function(a, b) {
a <- as.data.frame(unclass(rle(a)));
b <- as.data.frame(unclass(rle(b)));
t <- merge(a, b, by = "values", all = TRUE);
t$lengths.x[is.na(t$lengths.x)] <- 0;
t$diff <- t$lengths.y - t$lengths.x;
t <- t[!is.na(t$diff) & t$diff > 0, ];
return(rep(t$values, t$diff));
}
va <- c(1, 2);
vb <- c(1, 2) # NA or NULL
f(va, vb);
#numeric(0)
vb <- c(2, 2) # 2
f(va, vb);
#[1] 2
vb <- c(1, 1) # 1
f(va, vb);
#[1] 1
vb <- c(1) # NA or NULL
f(va, vb);
#numeric(0)
vb <- c(2) # NA or NULL
f(va, vb);
#numeric(0)
vb <- c(3, 3) # c(3, 3)
#[1] 3 3
说明:我正在利用 rle
来比较 va
和 vb
中不同条目的长度(口是心非程度);然后仅报告那些尚未在 va
中的内容。
更新
这是一种使用递归函数的更简洁的方法。
f <- function(a, b) {
if (length(a) == 0 | length(b) == 0) return(NULL);
m <- data.frame(idx.a = 1:length(a), idx.b = match(a, b));
m <- m[complete.cases(m), ];
# Here is the recursive call
if (nrow(m) > 0) f(a[-m$idx.a[1]], b[-m$idx.b[1]]) else b;
}
va <- c(1, 2) # Original vector
f(va, c(1, 2));
#NULL
f(va, c(2, 2));
#[1] 2
f(va, c(1, 1));
#[1] 1
f(va, c(1));
#NULL
f(va, c(2));
#NULL
f(va, c(3, 3));
#[1] 3 3
关于r - 比较两个向量(包括多个项目),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48925564/