如何向量化此函数以返回索引向量?

时间:2011-01-19 15:08:30

标签: r

我是R的新手,正在尝试处理apply系列函数。具体来说,我正在尝试编写一个高阶函数,它将接受2个字符向量,“host”和“guest”(不需要相同的长度),并返回一个与“host”相同长度的索引向量“,结果元素对应于客人的指数(如果不存在,则为NA)。

host <- c("A","B","C","D")
guest <- c("D","C","A","F")

matchIndices <- function(x,y)
{
  return(match(x,y))
}

此代码按预期返回3:

matchIndices(host[1],guest)

这是我想用简洁的应用函数替换的循环(sapply?)

for (i in 1:length(host)) 
{ idx <- matchIndices(host[i],guest); 
  cat(paste(idx,host[i],"\n",sep=";"))
}

这段代码“有效”,因为它产生下面的输出,但我真的希望结果是一个向量,我有一种预感,其中一个应用函数可以解决这个问题。我只是坚持如何写它。非常感激任何的帮助。感谢。

3; A; NA; B; 2; C; 1; d;

3 个答案:

答案 0 :(得分:8)

host <- c("A","B","C","D")
guest <- c("D","C","A","F")

matchIndices <- function(x,y) {
    return(match(x,y))
}

一种(低效)方式是sapply超过host向量,传入guest作为参数(请注意,您可以将其简化为sapply(host, match, guest),但这说明接近这类事情的一般方法):

> sapply(host, matchIndices, guest)
 A  B  C  D 
 3 NA  2  1

但是,这可以使用match 直接完成,因为它接受向量的第一个参数:

> match(host, guest)
[1]  3 NA  2  1

如果您想要一个命名向量作为输出,

> matched <- match(host, guest)
> names(matched) <- host
> matched
 A  B  C  D 
 3 NA  2  1

可以包装成函数

matchIndices2 <- function(x, y) {
    matched <- match(x, y)
    names(matched) <- x
    return(matched)
}

返回

> matchIndices2(host, guest)
 A  B  C  D 
 3 NA  2  1

如果真的希望将名称和匹配组合在一起成为字符串向量,那么:

> paste(match(host, guest), host, sep = ";")
[1] "3;A"  "NA;B" "2;C"  "1;D"

答案 1 :(得分:3)

如果你想要host;guestNum格式的输出向量,你可以使用do.callpastematch,如下所示:

> do.call(paste, list(host, sapply(host, match, guest), sep = ';'))                                                                                     
[1] "A;3"  "B;NA" "C;2"  "D;1" 

答案 2 :(得分:2)

sapply(host , function(x) which(guest==x))
$A
[1] 3

$B
integer(0)

$C
[1] 2

$D
[1] 1


unlist(sapply(host , function(x) which(guest==x)))

    A C D 
    3 2 1 

paste(host, sapply(host , function(x) which(guest==x)), sep=":", collapse=" ")
[1] "A:3 B:integer(0) C:2 D:1"