Как я могу векторизовать эту функцию, чтобы вернуть индексный вектор? - PullRequest
5 голосов
/ 19 января 2011

Я новичок в R и пытаюсь разобраться в семействе функций apply. В частности, я пытаюсь написать функцию более высокого порядка, которая будет принимать 2 символьных вектора, "host" и "guest" (которые не обязательно должны быть одинаковой длины) и возвращать мне индексный вектор такой же длины, что и "host ", с результирующими элементами, соответствующими их индексам в госте (нет, если нет).

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)

Это цикл, который я бы хотел заменить краткой функцией apply (sapply?)

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

Этот код «работает» в том смысле, что он производит выходные данные ниже, но я действительно хочу, чтобы результат был вектором, и я догадываюсь, что одна из функций применения справится с задачей. Я просто застрял на том, как написать это. Любая помощь будет наиболее ценной. Благодаря.

3; А; Н.А., B; 2; С; 1, D;

Ответы [ 3 ]

8 голосов
/ 19 января 2011
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"
3 голосов
/ 19 января 2011

если вы хотите получить вектор вывода в формате host;guestNum, вы должны использовать do.call, paste, match следующим образом:

> do.call(paste, list(host, sapply(host, match, guest), sep = ';'))                                                                                     
[1] "A;3"  "B;NA" "C;2"  "D;1" 
2 голосов
/ 19 января 2011
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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...