Suponha que eu tenha uma matriz 2 e uma função que use um vetor 2 como um de seus argumentos. Gostaria de aplicar a função a cada linha da matriz e obter um vetor n. Como fazer isso em R?
Por exemplo, eu gostaria de calcular a densidade de uma distribuição normal padrão 2D em três pontos:
bivariate.density(x = c(0, 0), mu = c(0, 0), sigma = c(1, 1), rho = 0){
exp(-1/(2*(1-rho^2))*(x[1]^2/sigma[1]^2+x[2]^2/sigma[2]^2-2*rho*x[1]*x[2]/(sigma[1]*sigma[2]))) * 1/(2*pi*sigma[1]*sigma[2]*sqrt(1-rho^2))
}
out <- rbind(c(1, 2), c(3, 4), c(5, 6))
Como aplicar a função a cada linha de out
?
Como passar valores para os outros argumentos além dos pontos para a função da maneira que você especificar?
apply()
- varre por linha (quando o segundo argumento é 1, mais por coluna), e a linha (ou coluna) atual é sempre o primeiro argumento. É assim que as coisas são definidas.MARGIN
argumento. Aqui, significa aplicar a função às linhas (a primeira dimensão emdim(M)
). Se fosse 2, aplicaria a função às colunas.Caso deseje aplicar funções comuns como soma ou média, você deve usar
rowSums
ourowMeans
uma vez que são mais rápidas que aapply(data, 1, sum)
abordagem. Caso contrário, fique comapply(data, 1, fun)
. Você pode passar argumentos adicionais após o argumento FUN (como Dirk já sugeriu):Então você pode fazer algo assim:
fonte
Aqui está um pequeno exemplo de aplicação de uma função a cada linha de uma matriz. (Aqui, a função aplicada normaliza todas as linhas para 1.)
Nota: O resultado do
apply()
teve que ser transposto usandot()
para obter o mesmo layout que a matriz de entradaA
.Resultado:
fonte
O primeiro passo seria criar o objeto de função e aplicá-lo. Se você deseja um objeto de matriz que tenha o mesmo número de linhas, é possível predefini-lo e usar o formulário [] conforme ilustrado (caso contrário, o valor retornado será simplificado para um vetor):
Se você deseja usar outros parâmetros que não sejam o padrão, a chamada deve incluir argumentos nomeados após a função:
apply () também pode ser usado em matrizes dimensionais mais altas e o argumento MARGIN pode ser um vetor e um único inteiro.
fonte
A aplicação faz bem o trabalho, mas é bastante lenta. Usar sapply e vapply pode ser útil. O rowwise do dplyr também pode ser útil. Vamos ver um exemplo de como criar produtos com linhas de qualquer quadro de dados.
Observe que atribuir a variável antes de usar vapply / sapply / apply é uma boa prática, pois reduz muito o tempo. Vamos ver os resultados da marca de microbench
Dê uma olhada cuidadosa em como t () está sendo usado
fonte
b <- t(iris[1:10, 1:3])
eapply(b, 2 prod)
.Outra abordagem, se você deseja usar uma parte variável do conjunto de dados em vez de um único valor, é usar
rollapply(data, width, FUN, ...)
. O uso de um vetor de larguras permite aplicar uma função em uma janela variável do conjunto de dados. Eu usei isso para criar uma rotina de filtragem adaptativa, embora não seja muito eficiente.fonte