match
match函数的声明如下:
match(x, table, nomatch = NA_integer_, incomparables = NULL)
x: 向量, 要匹配的值;
table: 向量, 被匹配的值;
nomatch: 没匹配上的返回值, 必须是整数;
incomparables: 指定不能用来匹配的值.
match函数是一个完全匹配函数, 当两个元素类型不一样时, 如果进行类型转换后匹配得上的话, 则仍可匹配, 可看下例.
match(c(1, "TRUE"), c("1", T))
pmatch
pmatch函数的声明如下:
pmatch(x, table, nomatch = NA_integer_, duplicates.ok = FALSE)
x: 向量, 要匹配的值;
table: 向量, 被匹配的值;
nomatch: 没匹配上的返回值, 必须是整数;
duplicates.ok: table里面的元素是否可以适用多次.
pmatch函数是一个部分匹配函数, 依次从x里面挑出元素, 对照table进行匹配, 若匹配上则剔除匹配上的值, 不再参与下次匹配, duplicate.ok可设置是否剔除; 对于某一个元素, 匹配一共分成三步:
1. 如果可以完全匹配, 则认为匹配上了, 返回table中的位置;
2. 不满足上述条件, 如果是唯一部分匹配, 则返回table中的位置;
3. 不满足上述条件, 则认为没有值与其匹配上.
pmatch(rep(1, 3), rep(1, 5))pmatch(rep(1, 3), rep(1, 5), duplicates.ok = TRUE)
运用
setdiff是R语言用来实现集合的减法的函数, 函数的声明如下:
setdiff(x, y)
函数的定义如下:
function (x, y) { x <- as.vector(x) y <- as.vector(y) unique(if (length(x) || length(y)) x[match(x, y, 0L) == 0L] else x)}
不难分析, 函数的返回值是不重复的, 但是也有很多情况下, x中元素是有重复的, y中元素是有重复的, 而我们想获得的结果也允许重复的, 那么这就不符合我们的预期了, 下面我们来改写下这个函数.
分析下简单情形, 如果y中的元素全都出现在x中, 那么新函数可以如下:
function (x, y) { x <- as.vector(x) y <- as.vector(y) if (length(x) || length(y)) x[is.na(pmatch(x, y))] else x}
所以, 若y中元素既有在x中又有不在x中时, 只需将在x中的元素找出来即可, 那么新函数如下:
function (x, y) { x <- as.vector(x) y <- as.vector(y) if (length(x) || length(y)) x[is.na(pmatch(x, y[!is.na(match(y, x))]))] else x}