R: Tipos de dados no R: 6 tipos básicos e conversão de tipos
Última atualização: 2026-08-26
Na aula anterior, aprendemos sobre atribuição e saída. Todos os dados nos programas em R — números, texto e valores booleanos — têm seus próprios “tipos” distintos. Nesta aula, exploraremos detalhadamente os seis tipos básicos de dados do R e dominaremos a “conversão de tipos”, uma habilidade essencial para a ciência de dados no R.
O R é uma linguagem de tipagem dinâmica, mas isso não significa que os tipos não sejam importantes — 90% dos erros no R estão relacionados a conversões de tipos.
1. O que você vai aprender
- Os 6 tipos básicos de dados no R (numérico, inteiro, caractere, lógico, complexo, bruto)
- A diferença entre
typeof()eclass() is.*Família de funções de verificação de tiposas.*Família de funções de conversão de tipos- As diferenças entre os quatro valores especiais (NA, NaN, Inf, NULL)
- Cenários comuns de conversão de tipos em aplicações do mundo real
2. A armadilha do “aparentemente igual”
Antes de escrever qualquer código, vamos dar uma olhada em um exemplo que confunde inúmeros iniciantes:
# These two numbers look the same, but R considers them "unequal"
1 == 1L
# [1] FALSE
# Verify their types
typeof(1)
# [1] "double" (Double-precision floating-point numbers)
typeof(1L)
# [1] "integer" (Integer)
Isso não é contraintuitivo? No R, “1” e “1L” não são a mesma coisa. Nesta aula, vamos desvendar todos os segredos dos tipos de dados do R.
3. Os 6 tipos básicos de dados no R
Todos os dados no R pertencem a um dos seis tipos básicos a seguir:
graph TB
A[R Data Types]
A --> B[numeric<br/>Double-precision floating-point numbers<br/>Default number]
A --> C[integer<br/>Integer<br/>Need to add L Suffix]
A --> D[character<br/>String<br/>Quotation marks must be used]
A --> E[logical<br/>Logical value<br/>TRUE/FALSE]
A --> F[complex<br/>Plural<br/>1+2i]
A --> G[raw<br/>Byte<br/>as.raw 0xff]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#cce5ff
style D fill:#d4edda
style E fill:#f8d7da
style F fill:#e1d4ff
style G fill:#ffe1e1
(1) Tabela resumida dos 6 tipos
| Tipo | Significado | Exemplo | O que o typeof() retorna |
|---|---|---|---|
| numérico | Número de ponto flutuante de dupla precisão (padrão) | 3.14, -2.5, 1e3 |
"double" |
| inteiro | Inteiro (deve ter o sufixo L) |
1L, 100L, -5L |
"integer" |
| caractere | String (deve estar entre aspas) | "Hello", 'R' |
"character" |
| lógico | Valor lógico (booleano) | TRUE, FALSE |
"logical" |
| complexo | plural | 1+2i, 3-4i |
"complex" |
| bruto | Tipo de byte | as.raw(0xff) |
"raw" |
(2) Explicação detalhada de cada tipo
# numeric —— Double-precision floating-point numbers(Default number)
x <- 3.14
typeof(x)
# [1] "double"
# integer -- Strict Integers (Add L Suffix)
x <- 10L
typeof(x)
# [1] "integer"
# character —— String
x <- "Hello R"
typeof(x)
# [1] "character"
# logical —— Logical value(Must be all uppercase)
x <- TRUE
typeof(x)
# [1] "logical"
# complex —— Plural
x <- 1 + 2i
typeof(x)
# [1] "complex"
TRUE não pode ser escrito como true ou True; se isso ocorrer, será gerado um erro object 'true' not found.
(3) Números inteiros x números de ponto flutuante: quando usar cada um?
| Cenário | Tipo recomendado | Motivo |
|---|---|---|
| Cálculos matemáticos gerais | numéricos | Padrão do R; não é preciso se preocupar com isso |
| Matrizes numéricas grandes (mais de 1 bilhão de elementos) | inteiro | Economiza metade da memória |
| Operações bit a bit, IDs, contagem | inteiro | Semanticamente inequívoco |
Resultados de comparações em ponto flutuante, sqrt(), etc. |
numérico | As operações matemáticas são, por natureza, em ponto flutuante |
# Performance Comparison(1 A billion integers vs 1 A billion floating-point numbers)
# integer: ~400 MB
# numeric: ~800 MB
# Not required in normal situations integer,numeric That's enough
integer durante a fase inicial. A menos que esteja realizando cálculos em grande escala (mais de 1 bilhão de elementos), o numeric é suficiente.
4. typeof() x class(): duas funções que costumam ser confundidas
O R possui duas funções que podem verificar o “tipo”, mas ambas têm significados diferentes.
(1) Um guia visual rápido sobre as diferenças
graph TB
A["R Object"] --> B["typeof()<br/>Bottom Layer C Type<br/>6 Basic Types"]
A --> C["class()<br/>Business OOP Class<br/>data.frame / Date / factor"]
B --> D["double / integer<br/>character / logical<br/>complex / raw"]
C --> E["Business Concepts<br/>(20+ kinds)"]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#d4edda
(2) Comparação real
# 1. Ordinary Vectors:The two are consistent
x <- 1:10
typeof(x)
# [1] "integer"
class(x)
# [1] "integer"
# 2. Data Frame: The two are different!
y <- data.frame(a = 1:3, b = c("x", "y", "z"))
typeof(y)
# [1] "list" ← The bottom layer is list
class(y)
# [1] "data.frame" ← In business terms, it's a data frame.
(3) Recomendações de seleção
| Cenário | Qual usar |
|---|---|
| Quer saber “o que é isso no R” | typeof() |
| Quer saber “o que isso significa para a empresa” | class() |
| Iniciantes | Recomendado class() (mais intuitivo) |
5. Verificação de tipos: a família de funções is.*
O R oferece a família de funções is.* para verificação de tipos, e todas as funções retornam TRUE ou FALSE.
(1) Funções comuns de verificação
| Função de verificação | Finalidade | Exemplos de resultados |
|---|---|---|
is.numeric(x) |
É numérico (numérico ou inteiro) | is.numeric(1L) → TRUE |
is.integer(x) |
É um inteiro estrito (com o sufixo “L”) | is.integer(1) → FALSO |
is.character(x) |
É uma string | is.character("a") → TRUE |
is.logical(x) |
é um valor lógico | is.logical(TRUE) → TRUE |
is.na(x) |
Um valor ausente é NA | is.na(NA) → TRUE |
is.null(x) |
É NULL (valor vazio) | is.null(NULL) → TRUE |
(2) Principal armadilha: is.numeric() não faz distinção entre inteiros e valores do tipo double
# is.numeric() is the "superset" of is.integer()
is.numeric(1) # [1] TRUE
is.numeric(1L) # [1] TRUE
is.integer(1) # [1] FALSE
is.integer(1L) # [1] TRUE
is.numeric(); para verificar se é um inteiro estrito, use is.integer().
6. Conversão de tipos: a família de funções as.*
A família de funções as.* no R pode converter um tipo em outro.
(1) Funções comuns de conversão
| Função de conversão | Finalidade | Comportamento em caso de falha |
|---|---|---|
as.numeric(x) |
→ Número | Retornar NA + Aviso |
as.integer(x) |
→ Número inteiro | Truncar decimais |
as.character(x) |
→ String | Sempre bem-sucedido |
as.logical(x) |
→ Valor lógico | 0 → FALSO, outros números → VERDADEIRO |
(2) O custo de uma conversão malsucedida
# String → Numbers(Success)
as.numeric("3.14")
# [1] 3.14
# String → Numbers(Failure)
as.numeric("Hello")
# Warning: NAs introduced by coercion
# [1] NA
NA:
# One failure won't stop me,But there will be a warning
as.numeric(c("1", "2", "abc", "4"))
# Warning: NAs introduced by coercion
# [1] 1 2 NA 4
(3) Cenário prático: incompatibilidade de tipos após a leitura de um arquivo CSV
Uma das armadilhas mais comuns ao ler arquivos CSV é que as colunas numéricas sejam interpretadas como caracteres:
# Suppose we read one CSV,All columns are character
df <- data.frame(
id = c("1", "2", "3"),
value = c("10.5", "20.3", "30.1")
)
# Before Conversion
str(df)
# 'data.frame': 3 obs. of 2 variables:
# $ id : chr "1" "2" "3"
# $ value: chr "10.5" "20.3" "30.1"
# After conversion
df$id <- as.numeric(df$id)
df$value <- as.numeric(df$value)
str(df)
# $ id : num 1 2 3
# $ value: num 10.5 20.3 30.1
readr::read_csv(), ele inferirá automaticamente o tipo — ele é muito mais inteligente que o read.csv(), então esse problema não ocorrerá.
- Valores especiais: NA / NaN / Inf / NULL
O R possui quatro valores especiais com significados completamente diferentes — a maior armadilha para iniciantes.
(1) A relação entre os quatro valores especiais
graph TB
A["Missing values/Null value"]
A --> B[NA<br/>Missing values Not Available<br/>Missing Data,Not assigned,Conversion Failed]
A --> C[NaN<br/>Non-numeric Not a Number<br/>Not defined mathematically]
A --> D[Inf<br/>Infinity Infinity<br/>1/0,exp 1000]
A --> E[NULL<br/>Empty object<br/>Undefined,Functions with no return value]
B --> F[Includes NaN]
style A fill:#fff3cd
style B fill:#d4edda
style C fill:#f8d7da
style D fill:#cce5ff
style E fill:#e1d4ff
(2) Tabela comparativa de quatro valores especiais
| Valor especial | tipo | Significado | Cenário de uso | Função de verificação |
|---|---|---|---|---|
| NA | lógico | Valor ausente | Dados ausentes, não atribuídos, falha na conversão | is.na() |
| Não é um número | duplo | não numérico | 0/0,sqrt(-1) |
is.nan() |
| Inf | double | infinito positivo | 1/0, exp(1000) |
is.infinite() |
| NULL | NULL | objeto vazio | indefinido, a função não retorna nenhum valor | is.null() |
(3) NA: O tipo mais comum de “dados ausentes”
# NA Participating in calculations is contagious(NA It won't disappear)
x <- c(1, 2, NA, 4)
sum(x)
# [1] NA <- The entire result turned out NA
# Must use na.rm = TRUE Skip NA
sum(x, na.rm = TRUE)
# [1] 7
# Inspection NA Location
is.na(x)
# [1] FALSE FALSE TRUE FALSE
(4) NaN: “Não definido” em matemática
# 0 Divide by 0
0 / 0
# [1] NaN
# Taking the square root of a negative number
sqrt(-1)
# Warning: NaNs produced
# [1] NaN
# NaN It is special. NA(NA a subset of)
is.na(NaN)
# [1] TRUE ← NaN Me too NA
(5) Informação: “Infinito” na matemática
# 1 Divide by 0
1 / 0
# [1] Inf
# A negative number divided by 0
-1 / 0
# [1] -Inf
# Inspection Inf
is.infinite(c(1, Inf, -Inf, 2))
# [1] FALSE TRUE TRUE FALSE
(6) NULL: Um objeto vazio (ou que nem sequer existe)
# NULL Doesn't take up memory
x <- NULL
length(x)
# [1] 0
# NA occupies 1 position, NULL disappears entirely
length(c(1, 2, NA, 4)) # [1] 4
length(c(1, 2, NULL, 4)) # [1] 3 ← NULL Swallowed whole
# Default return value for functions with no return value NULL
my_void_func <- function() { }
result <- my_void_func()
is.null(result)
# [1] TRUE
NA e NULL: NA significa “a posição existe, mas o valor é desconhecido”, enquanto NULL significa “a posição simplesmente não existe”. O primeiro é frequentemente usado para indicar dados ausentes, enquanto o segundo é frequentemente usado quando uma função não possui valor de retorno.
8. Exemplo completo: Exercício abrangente sobre conversão de tipos
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que reúne todos os conceitos abordados nesta aula.
▶ Exemplo: Limpeza de dados inseridos pelo usuário
# ============================================
# Cleaning User-Input Data
# Features:Convert a character vector to a number,Processing NA
# ============================================
# 1. Simulate from CSV Read"Dirty Data"(All of them character)
raw_data <- c("1", "2.5", "3.14", "abc", "5", "", "7.8")
cat("Raw Data:\n")
print(raw_data)
cat("Primitive Types:", typeof(raw_data), "\n\n")
# 2. Convert to a number ("abc" and "" will become NA)
nums <- as.numeric(raw_data)
cat("After conversion:\n")
print(nums)
# 3. See which ones are NA
na_positions <- is.na(nums)
cat("\nNA Location:")
print(na_positions)
# 4. Statistics NA Quantity
na_count <- sum(na_positions)
cat("\nNA Quantity:", na_count, "\n")
# 5. Keep only non- NA the number
clean_nums <- nums[!na_positions]
cat("\nData After Cleaning:")
print(clean_nums)
# 6. Statistical Indicators
cat("\n=== Statistical Indicators ===\n")
cat("Total Number of Elements:", length(raw_data), "\n")
cat("Valid Data:", length(clean_nums), "\n")
cat("Invalid data:", na_count, "\n")
cat("Total:", sum(clean_nums), "\n")
cat("Average:", round(mean(clean_nums), 2), "\n")
cat("Maximum value:", max(clean_nums), "\n")
cat("Minimum value:", min(clean_nums), "\n")
Resultado esperado (trecho):
Raw Data:
[1] "1" "2.5" "3.14" "abc" "5" "" "7.8"
Primitive Types: character
After conversion:
[1] 1.00 2.50 3.14 NA 5.00 NA 7.80
NA Location:
[1] FALSE FALSE FALSE TRUE FALSE TRUE FALSE
NA Quantity: 2
Data After Cleaning:
[1] 1.00 2.50 3.14 5.00 7.80
=== Statistical Indicators ===
Total Number of Elements: 7
Valid Data: 5
Invalid data: 2
Total: 19.44
Average: 3.89
Maximum value: 7.8
Minimum value: 1
(1) Procedimento
| Etapa | Ação | Descrição |
|---|---|---|
| 1 | Criar projeto no RStudio r-types |
File → New Project |
| 2 | Criar um novo script data_cleaning.R |
Copiar o código acima |
| 3 | Selecionar tudo → Ctrl+Enter |
Enviar para o console |
| 4 | Observe a saída | Veja a etiqueta “NA” e os resultados após a limpeza |
❓ Perguntas Frequentes
P: Qual devo usar,
typeof()ouclass()? R: Usetypeof()(6 tipos básicos) se quiser saber mais sobre os tipos internos subjacentes do R; useclass()(data.frame/Date/factor) se quiser saber mais sobre tipos de negócios. Para iniciantes, oclass()é mais intuitivo.
P: Por que
is.numeric(1L)retorna TRUE, masis.integer(1L)também retorna TRUE? R: Porqueis.numeric()é o “conjunto pai” deis.numeric()— um inteiro é sempre um valor numérico, mas o contrário não é verdadeiro. Recomendação: Useis.numeric()para verificar se um valor é um “número” e useis.integer()para verificar se é um “inteiro estrito”.
P: O que
as.numeric("3.14")eas.numeric("Hello")retornam? R: O primeiro retorna 3,14 (sucesso), enquanto o segundo retornaNAe exibe o avisoNAs introduced by coercion. Ao realizar conversões em lote, certifique-se de verificar o número de entradasis.na(); caso contrário, todos os cálculos subsequentes retornarão NA.
P: A que é igual
NA + 1? R: É igual aNA. NA é contagioso; o resultado de qualquer operação aritmética envolvendo NA é NA. Para contornar NA, use o parâmetrona.rm = TRUE(por exemplo,sum(x, na.rm = TRUE)).
P: Como faço para escolher entre
NULLeNA? R: UseNApara indicar “dados ausentes” (o local existe, mas o valor é desconhecido); useNULLpara indicar “objeto inexistente” (nem mesmo o local existe).NAé usado na grande maioria dos cenários de processamento de dados.
📖 Resumo
- Os 6 tipos básicos de dados do R: numérico (padrão), inteiro (com o sufixo
L), caractere (string), lógico (booleano), complexo (números complexos) e bruto (bytes) typeof()aborda os tipos de dados de baixo nível em C (6 tipos básicos);class()aborda os tipos de dados relacionados a negócios (data.frame, Date, factor) — Para iniciantes,class()será mais intuitivo- A família de funções
is.*verifica o tipo (retorna TRUE/FALSE); a família de funçõesas.*realiza uma conversão de tipo (retorna NA e emite um aviso se a conversão falhar) as.numeric()Corresponde tanto a números inteiros quanto a valores do tipo double; faz uma distinção rigorosa entre eles usandoas.integer()- Os quatro valores especiais têm significados diferentes: NA (valor ausente — infeccioso), NaN (não é um número), Inf (infinito) e NULL (objeto vazio — não existe)
- Métodos padrão para lidar com valores NA:
sum(x, na.rm = TRUE)Ignorar valores NA;!is.na(x)Filtrar valores NA
📝 Exercícios
-
Exercício básico: Defina seis variáveis que representem os seis tipos básicos de dados (numérico, inteiro, caractere, lógico, complexo, bruto). Use
typeof()para verificar o tipo de cada variável e salve capturas de tela da saída dos seis comandostypeof(). -
Problema básico: Use
as.numeric()para converter o vetor de caracteresc("1", "2.5", "3.14", "abc", "5")em números, registre as mensagens de aviso e os resultados da conversão, e useis.na()para identificar quais elementos se tornaram NA. Faça uma captura de tela da saída do console e salve-a. -
Exercício básico: No console do RStudio, calcule
0/0,1/0,-1/0esqrt(-1), anote cada resultado e useis.na(),is.nan()eis.infinite()para verificar a qual valor especial cada um deles pertence. -
Problema avançado: Defina um vetor
scores <- c(85, 92, NA, 78, NA, 95, 88). Requisitos: ① Calcule a pontuação total (excluindo os valores NA); ② Calcule a pontuação média (excluindo os valores NA, arredondada para 2 casas decimais); ③ Use!is.na()para filtrar os elementos que não sejam NA; ④ Conte o número de valores NA. Salve uma captura de tela do resultado de cada etapa. -
Desafio: Escreva um script em R para simular uma “incompatibilidade de tipos após a leitura de um arquivo CSV”: ① Construa manualmente um data.frame em que todas as colunas sejam do tipo
character; ② Useas.numeric()para converter em lote uma das colunas para o tipo numérico; ③ Usesum(is.na(df$col))para contar o número de elementos cuja conversão falhou; ④ Usepaste()para criar uma mensagem de aviso e exibi-la. Após executar o script, faça uma captura de tela e salve toda a saída do console.