R é uma linguagem de tipagem dinâmica, então em geral não é necessário especificar o tipo de uma variável. O tipo padrão é numeric, geralmente implementado como um número de ponto flutuante de precisão dupla. Para forçar o uso de inteiros de 32 bits, use o sufixo L (abreviação de Long).
Obter o "tipo" de um objeto é, por razões históricas, potencialmente confuso.
As funções typeof() e class() são parecidas, mas podem retornar resultados um pouco diferentes:
typeof(50)
#> [1] "double" # more specific: an implementation detail
typeof(50L)
##> [1] "integer"
class(50)
#> [1] "numeric" # less specific: ignores implementation details
class(50L)
#> [1] "integer"
Você também pode ver referências a mode(), que é parecido com typeof().
Ignore mode() e storage.mode().
Eles existem apenas para compatibilidade com versões anteriores.
O operador de atribuição preferido é <-.
Se você estiver trabalhando no RStudio, pode digitá-lo com o atalho de teclado Alt-minus.
x <- 42
avogadro <- 6.02e23
mystr <- "Hello, World!"
Usar = em vez de <- muitas vezes funciona, mas nem sempre, e é desencorajado por ser um estilo ruim.
Os operadores são em sua maioria parecidos com os de muitas outras linguagens, embora %% e %/% sejam mais incomuns.
Essa sintaxe com % é uma forma de chamar operadores infixos implementados como macros.
2 + 3 # 5
2 - 3 # -1
2 * 3 # 6
2 / 3 # 0.6666667
8 %/% 3 # 2 (integer division)
8 %% 3 # 2 (remainder)
2 ^ 3 # 8 (exponential)
Em R, # inicia um comentário de uma linha.
Não existe uma sintaxe separada para comentários de várias linhas.
Para definir uma função:
squareit <- function(x) {
x * x
}
Funções podem ter zero ou mais argumentos, separados por vírgulas.
Os parênteses () são necessários com function(), mesmo que não haja parâmetros.
É possível especificar valores padrão para os argumentos de uma função, mas eles devem vir depois de todos os argumentos sem valor padrão, e usamos = (não <-) para atribuir o valor padrão.
Como um exemplo um tanto inútil:
squareit <- function(x = 42) {
x * x
}
squareit()
#> [1] 1764
As chaves { } não são estritamente necessárias para corpos de função de uma linha, mas incluí-las é considerado um bom estilo.
R retorna automaticamente o valor final de uma função, como nos exemplos acima.
return() pode ser usado em qualquer lugar dentro do corpo da função para tornar explícito um valor de retorno.
Ele retorna o valor especificado imediatamente e encerra a função sem executar nenhuma das expressões restantes no corpo da função.
Uma chamada explícita a return() geralmente só é necessária se você quiser sair da função antes do fim e retornar um valor específico por algum motivo.
Um exemplo pode ser dentro de uma cláusula if-else.
Alguns desenvolvedores, no entanto, preferem retornos explícitos como questão de estilo de código.
Chamar uma função é igual a muitas outras linguagens:
squareit(3)
#> [1] 9
Veremos em conceitos futuros que o resultado 9 é na verdade um vetor de comprimento 1, e não um número escalar.
Daí a inclusão de [1] para indicar que este é o início do vetor.
is.vector(9)
#> [1] TRUE
Quase tudo em R é algum tipo de vetor!
O console do R exibiria o exemplo acima assim:
> squareit(3)
[1] 9
Os documentos deste syllabus seguem em sua maioria a convenção usada em vários livros didáticos de R: remover o prompt e comentar o resultado. Isso facilita copiar e colar os exemplos de código no console e executá-los.