A família Apply representa um conjunto de funções básicas do R que permite realizar operações sobre os dados contidos nas várias estruturas disponíveis (vetor, data frame, listas). digite no prompt R o seguinte comando
??base::apply
e você verá o conjunto de funções pertencentes a esta família,algumas delas não serão tratadas neste post.
A utilização destas funções permitem automatizar a aplicação das operações desejadas, permitindo assim ganhos de velocidade durante procedimentos que necessitam ser repetidos sobre todos os dados. No post de hoje vamos ver o funcionamento destas funções. Para iniciar vamos ver como funciona a função apply. O entendimento desta função permitirá a compreensão das demais.
Função Apply:
Considere a seguinte matriz 3×4 contendo números de 1 a 12 preenchidos por linha.
A <- matrix(1:12,nrow=3,byrow=TRUE) A #veja a matriz
Vamos supor que desejamos saber o valor total de cada linha desta matriz. Isto poderia ser feito manualmente da seguinte forma:
linha1<-sum(A[1,]) # soma os elementos da linha 1 linha2<-sum(A[2,]) # soma os elementos da linha 2 linha3<-sum(A[3,]) # soma os elementos da linha 3
Este processo é de longe a pior escolha. Para grandes conjuntos de dados ele se torna desgastante. No entanto podemos observar que há um padrão nos comandos utilizados, a função sum() é aplicada repetidamente sobre a matriz e somente o identificador da linha altera em cada procedimentos.
Podemos desenvolver uma função que automatize este processo. Esta função deve receber a estrutura contendo os dados, o sentido de busca (linha ou coluna) e a função que deve ser aplicada. A simples função abaixo pode ser utilizada com uma matriz ou data frame. O argumento “sentido” deve receber os valores “linha” ou “Coluna” (entre aspas). O argumento “função” pode ser uma função base do R (mean, sum, sd, min, max,…) ou uma função definida pelo usuário.
minhafunçãoApply <- function(x,sentido,função){ #sentido: "linha" ou "coluna" resultado <- c() fc<-função if(sentido==){ for (i in 1:nrow(x)){ resultado[i]<- fc(x[i,]) } } else{ for (i in 1:ncol(x)){ resultado[i] <- fc(x[,i]) } } return(resultado) } minhafunçãoApply(A,sentido="linha",sum) [1] 10 26
No exemplo acima a função base sum() foi aplicada a cada linha da matriz A e o resultado foi retornado (10,26,42). O mesmo resultado pode ser obtido com a função apply.
A função Apply, presente no pacote base, necessita de 3 argumentos para seu funcionamento: a matriz ou data frame contendo os dados, a indicação do sentido de aplicação da função, representado pelos números 1 (linha) ou 2 (coluna) e a função a ser aplicada
> apply(A,1,sum) [1] 10 26 42
Podemos também adicionar nossa pŕopria função:
#Função para adicionar 10 ao total da linha ou coluna funcao_usuario <- function(x){ return(sum(x)+10) } minhafuncao( A,sentido="linha",funcao_usuario) ou [1] 20 36 52 apply(A, 1, funcao_usuario) [1] 20 36 52
Funções lapply e sapply
As funções lapply e sapply são uma variação utilizada para aplicar um procedimento aos elementos de uma lista. Esta funções diferem somente na forma como os resultados são mostrados. Para a função lapply o resultado esta na forma de lista, enquanto na sapply o resultado é apresentado na forma de vetor.
set.seed(5) #Cria uma lista contendo os vetores "consumo", "peso" e um data frame "data" contendo duas colunas (a e b) com 10 linhas minhalista <- list( consumo=c(1.25, 1.54,1.45) , peso = c(45,50,53),data=data.frame(a=rep(1:5,each=2),b=rnorm(10))) #Soma todos cada um dos elementos da lista e retorna uma lista com os valores lapply(minhalista,sum) $consumo [1] 4.24 $peso [1] 148 $data [1] 29.21148 #Soma todos cada um dos elementos da lista e retorna um vetor com os valores > sapply(minhalista,sum) consumo peso data 4.24000 148.00000 29.21148 #Soma somente as colunas do elemento data(um dataframe) retorna uma lista com os valores > lapply(minhalista$data,sum) $a [1] 30 $b [1] -0.7885155
Também é possível utilizar função definida pelo usuário
lapply(minhalista$data,funcao_usuario) # adiciona 10 a cada elemendo do dataframe de nome data contido na lista e soma cada coluna deste dataframe
Tapply
A função tapply é utilizada para aplicar um procedimento a diferentes partes dos dados dentro de um array, matriz ou data frame. Ela difere das demais funções vista até aqui por exigir a existencia de uma variável categórica o qual servirá para agrupar os dados aos diferentes níveis. Ela é muito útil quando queremos saber, por exemplo, a média de cada um dos tratamentos avaliados em um experimento.
A função tapply utiliza 3 argumentos: (1)A estrutura contendo os dados (vetor,matriz,data frame, array) onde será aplicada a operação; (2) Um vetor de variáveis categóricas que determina a estrutura dos dados; (3) a função que desejamos aplicar.
consumo <- c(13.10,15.20,16.10,14.75,15.35,16.20) #cria o vetor de resposta grupo<-as.factor(c("15%PB","18%PB","18%PB","15%PB","15%PB","18%PB"))#cria vetor de fatores indicando o grupo experimental #Obtêm a média de consumo em função do concentração de PB da dieta tapply(consumo,grupo,mean)
mapply
A função mapply é uma versão multivariada da função lapply e sapply. As funções lapply e sapply atuam somente sobre os elementos de uma única lista. No caso da função mapply a função é aplicada sobre o primeiro elemento de cada um dos argumentos, em seguida ao segundo elemento, seguindo ao terceiro, e assim por diante. Os argumentos podem ser listas ou vetores. Vamos ver um simples exemplo para ilustrar seu funcionamento
a<-c(1,2,3,4) b<-c(5,6,7,8) mapply(sum, a,b) #soma os elementos dos vetores a e b
O que fizemos ao utilizar esta função foi:
(a[1]+b[1]);(a[2]+b[2]);(a[3]+b[3]);(a[4]+b[4])
Vejamos outro exemplo utilizando uma lista:
L1 <- list(a = LETTERS[c(4,6,12,6)], b = LETTERS[c(1,5,21,1)]) L2 <- list(c = LETTERS[c(4,14,22,20)], d = LETTERS[c(15,15,1,15)]) #duas listas L1 e L2 contendo os elementos a,b e c,d respectivamente contendo letras do alfabeto #visualize as listas L1 L2 # une as letras, contidas na mesma posição de cada vetor da lista L1 e L2 para escrever as palavras DADO, FENO,LUVA e FATO mapply(paste, l1$a, l1$b, l2$c, l2$d)