我需要找到新向量(vb)中的哪些元素已添加到另一个向量(va)中。例如,如果有一个" 2"在va,但是两个" 2"在vb中,然后是一个" 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%等等,但无法让它考虑多个实例。这感觉非常简单......
答案 0 :(得分:2)
以下内容将再现您的预期结果。就像一个诚实的单挑,我对我的解决方案并不满意,这看起来很奇怪:
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
答案 1 :(得分:1)
不是最优雅的,但它适用于所有情况:
Diff_frequency <- function(va,vb){
df <- merge(as.data.frame(table(va)), as.data.frame(table(vb)), by.x="va", by.y="vb", all=T)
df$Freq.x[is.na(df$Freq.x)] <- 0
df$Dif <- df$Freq.y - df$Freq.x
df$Dif[is.na(df$Dif) | df$Dif < 0] <- 0
return(rep(as.numeric(as.character(df[,1])), df$Dif))
}
Diff_frequency(va,vb)
输出示例:
va=c(1,1,1,2,2,2,3)
vb=c(1,1,4,4,2,2,5)
Diff_frequency(va,vb)
[1] 4 4 5
va=c(1,1,1,2,2,2,3)
vb=c(1,1,1,1,2,2,2,3,3,5)
Diff_frequency(va,vb)
1] 1 3 5
va=c(1,1,1,2,2,2,3)
vb=c(1,1,2,3)
Diff_frequency(va,vb)
numeric(0)