Buscar..


Sintaxis

  • data.frame (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, stringsAsFactors = default.stringsAsFactors ())

  • as.data.frame (x, row.names = NULL, opcional = FALSE, ...) # función genérica

  • as.data.frame (x, ..., stringsAsFactors = default.stringsAsFactors ()) # Método S3 para la clase 'carácter'

  • as.data.frame (x, row.names = NULL, opcional = FALSE, ..., stringsAsFactors = default.stringsAsFactors ()) # Método S3 para la clase 'matrix'

  • is.data.frame (x)

Crear un data.frame vacío

Un data.frame es un tipo especial de lista: es rectangular . Cada elemento (columna) de la lista tiene la misma longitud, y donde cada fila tiene un "nombre de fila". Cada columna tiene su propia clase, pero la clase de una columna puede ser diferente de la clase de otra columna (a diferencia de una matriz, donde todos los elementos deben tener la misma clase).

En principio, un data.frame no puede tener filas ni columnas:

> structure(list(character()), class = "data.frame")
NULL
<0 rows> (or 0-length row.names)

Pero esto es inusual. Es más común que un data.frame tenga muchas columnas y muchas filas. Aquí hay un data.frame con tres filas y dos columnas ( a es a clase numérica y b es una clase de caracteres):

> structure(list(a = 1:3, b = letters[1:3]), class = "data.frame")
[1] a b
<0 rows> (or 0-length row.names)

Para que se pueda imprimir el data.frame, tendremos que proporcionar algunos nombres de fila. Aquí usamos sólo los números 1: 3:

> structure(list(a = 1:3, b = letters[1:3]), class = "data.frame", row.names = 1:3)
  a b
1 1 a
2 2 b
3 3 c

Ahora resulta obvio que tenemos un data.frame con 3 filas y 2 columnas. Puede verificar esto usando nrow() , ncol() y dim() :

> x <- structure(list(a = numeric(3), b = character(3)), class = "data.frame", row.names = 1:3)
> nrow(x)
[1] 3
> ncol(x)
[1] 2
> dim(x)
[1] 3 2

R proporciona otras dos funciones (además de la structure() ) que se pueden usar para crear un data.frame. El primero se llama, intuitivamente, data.frame() . Comprueba para asegurarse de que los nombres de columna que proporcionó son válidos, que los elementos de la lista tienen la misma longitud y proporciona algunos nombres de fila generados automáticamente. Esto significa que la salida de data.frame() ahora puede ser siempre exactamente lo que espera:

> str(data.frame("a a a" = numeric(3), "b-b-b" = character(3)))
'data.frame':   3 obs. of  2 variables:
 $ a.a.a: num  0 0 0
 $ b.b.b: Factor w/ 1 level "": 1 1 1

La otra función se llama as.data.frame() . Esto se puede usar para forzar a un objeto que no es un data.frame a que sea un data.frame ejecutándolo a través de data.frame() . Como ejemplo, consideremos una matriz:

> m <- matrix(letters[1:9], nrow = 3)
> m
     [,1] [,2] [,3]
[1,] "a"  "d"  "g" 
[2,] "b"  "e"  "h" 
[3,] "c"  "f"  "i" 

Y el resultado:

> as.data.frame(m)
  V1 V2 V3
1  a  d  g
2  b  e  h
3  c  f  i
> str(as.data.frame(m))
'data.frame':   3 obs. of  3 variables:
 $ V1: Factor w/ 3 levels "a","b","c": 1 2 3
 $ V2: Factor w/ 3 levels "d","e","f": 1 2 3
 $ V3: Factor w/ 3 levels "g","h","i": 1 2 3

Subcontratar filas y columnas de un marco de datos

Sintaxis para acceder a filas y columnas: [ , [[ , y $

Este tema cubre la sintaxis más común para acceder a filas y columnas específicas de un marco de datos. Estos son

  • Como una matrix con data[rows, columns] corchetes individuales data[rows, columns]
    • Usando números de fila y columna
    • Usando nombres de columnas (y filas)
  • Como una list :
    • Con paréntesis de data[columns] para obtener un marco de datos
    • Con data[[one_column]] dobles corchetes data[[one_column]] para obtener un vector
  • Con $ para una columna de data$column_name

Usaremos el marco de datos mtcars para ilustrar.

Como una matriz: data[rows, columns]

Con índices numéricos

Usando el marco de datos mtcars , podemos extraer filas y columnas usando [] corchetes con una coma incluida. Los índices antes de la coma son filas:

# get the first row
mtcars[1, ]
# get the first five rows
mtcars[1:5, ]

Del mismo modo, después de la coma están las columnas:

# get the first column
mtcars[, 1]
# get the first, third and fifth columns:
mtcars[, c(1, 3, 5)]

Como se muestra arriba, si las filas o columnas se dejan en blanco, se seleccionarán todas. mtcars[1, ] indica la primera fila con todas las columnas.

Con nombres de columna (y fila)

Hasta ahora, esto es idéntico a cómo se accede a las filas y columnas de matrices. Con data.frame s, la mayoría de las veces es preferible usar un nombre de columna para un índice de columna. Esto se hace usando un character con el nombre de la columna en lugar de numeric con un número de columna:

# get the mpg column
mtcars[, "mpg"]
# get the mpg, cyl, and disp columns
mtcars[, c("mpg", "cyl", "disp")]

Aunque menos comunes, los nombres de las filas también se pueden usar:

mtcars["Mazda Rx4", ]

Filas y columnas juntas

Los argumentos de fila y columna se pueden utilizar juntos:

# first four rows of the mpg column
mtcars[1:4, "mpg"]

# 2nd and 5th row of the mpg, cyl, and disp columns
mtcars[c(2, 5), c("mpg", "cyl", "disp")]

Una advertencia sobre las dimensiones:

Al usar estos métodos, si extrae varias columnas, obtendrá un marco de datos nuevamente. Sin embargo, si extrae una sola columna, obtendrá un vector, no un marco de datos en las opciones predeterminadas.

## multiple columns returns a data frame
class(mtcars[, c("mpg", "cyl")])
# [1] "data.frame"
## single column returns a vector
class(mtcars[, "mpg"])
# [1] "numeric"

Hay dos maneras de evitar esto. Una es tratar el marco de datos como una lista (ver más abajo), la otra es agregar un argumento drop = FALSE . Esto le dice a R que no "suelte las dimensiones no utilizadas":

class(mtcars[, "mpg", drop = FALSE])
# [1] "data.frame"

Tenga en cuenta que las matrices funcionan de la misma manera: de forma predeterminada, una sola columna o fila será un vector, pero si especifica drop = FALSE , puede mantenerla como una matriz de una columna o de una fila.

Como una lista

Los marcos de datos son esencialmente list s, es decir, son una lista de vectores de columnas (que todos deben tener la misma longitud). Las listas se pueden subcontratar utilizando corchetes simples [ para una sub-lista, o corchetes dobles [[ para un elemento individual.

Con data[columns] corchetes individuales data[columns]

Cuando use corchetes simples y sin comas, obtendrá una columna de vuelta porque los marcos de datos son listas de columnas.

mtcars["mpg"]
mtcars[c("mpg", "cyl", "disp")]
my_columns <- c("mpg", "cyl", "hp")
mtcars[my_columns]
Corchetes simples como una lista vs. corchetes simples como una matriz

La diferencia entre los data[columns] y los data[, columns] es que cuando se trata el data.frame como una list (sin comas entre paréntesis), el objeto devuelto será un data.frame . Si usa una coma para tratar el data.frame como una matrix , la selección de una sola columna devolverá un vector, pero la selección de varias columnas devolverá un data.frame .

## When selecting a single column
## like a list will return a data frame
class(mtcars["mpg"])
# [1] "data.frame"
## like a matrix will return a vector
class(mtcars[, "mpg"])
# [1] "numeric"

Con data[[one_column]] dobles corchetes data[[one_column]]

Para extraer una sola columna como un vector al tratar su data.frame como una list , puede usar corchetes dobles [[ . Esto solo funcionará para una sola columna a la vez.

# extract a single column by name as a vector 
mtcars[["mpg"]]

# extract a single column by name as a data frame (as above)
mtcars["mpg"]

Usando $ para acceder a las columnas

Se puede extraer una sola columna usando el acceso directo mágico $ sin usar un nombre de columna entre comillas:

# get the column "mpg"
mtcars$mpg

Las columnas a las que se accede con $ siempre serán vectores, no marcos de datos.

Inconvenientes de $ para acceder a columnas

El $ puede ser un atajo conveniente, especialmente si está trabajando en un entorno (como RStudio) que completará automáticamente el nombre de la columna en este caso. Sin embargo, $ tiene inconvenientes: utiliza una evaluación no estándar para evitar la necesidad de comillas, lo que significa que no funcionará si el nombre de su columna se almacena en una variable.

my_column <- "mpg"
# the below will not work
mtcars$my_column
# but these will work
mtcars[, my_column]  # vector
mtcars[my_column]    # one-column data frame
mtcars[[my_column]]  # vector

Debido a estas preocupaciones, $ se utiliza mejor en sesiones R interactivas cuando los nombres de sus columnas son constantes. Para uso programático , por ejemplo, al escribir una función generalizable que se usará en diferentes conjuntos de datos con diferentes nombres de columna, se debe evitar $ .

También tenga en cuenta que el comportamiento predeterminado es utilizar la coincidencia parcial solo cuando se extrae de objetos recursivos (excepto entornos) por $

# give you the values of "mpg" column 
# as "mtcars" has only one column having name starting with "m"
mtcars$m 
# will give you "NULL" 
# as "mtcars" has more than one columns having name starting with "d"
mtcars$d

Indexación avanzada: índices negativos y lógicos.

Siempre que tengamos la opción de usar números para un índice, también podemos usar números negativos para omitir ciertos índices o un vector booleano (lógico) para indicar exactamente qué elementos mantener.

Índices negativos omiten elementos.

mtcars[1, ]   # first row
mtcars[ -1, ] # everything but the first row
mtcars[-(1:10), ] # everything except the first 10 rows

Los vectores lógicos indican elementos específicos para mantener

Podemos usar una condición como < para generar un vector lógico, y extraer solo las filas que cumplan con la condición:

# logical vector indicating TRUE when a row has mpg less than 15
# FALSE when a row has mpg >= 15
test <- mtcars$mpg < 15 

# extract these rows from the data frame 
mtcars[test, ]

También podemos omitir el paso de guardar la variable intermedia.

# extract all columns for rows where the value of cyl is 4.
mtcars[mtcars$cyl == 4, ]
# extract the cyl, mpg, and hp columns where the value of cyl is 4
mtcars[mtcars$cyl == 4, c("cyl", "mpg", "hp")]

Funciones de conveniencia para manipular data.frames.

Algunas funciones de conveniencia para manipular data.frames son subset() , transform() , with() y within() .

subconjunto

La función de subset() permite data.frame un data.frame de una manera más conveniente (el subconjunto también funciona con otras clases):

subset(mtcars, subset = cyl == 6, select = c("mpg", "hp"))
                mpg  hp
Mazda RX4      21.0 110
Mazda RX4 Wag  21.0 110
Hornet 4 Drive 21.4 110
Valiant        18.1 105
Merc 280       19.2 123
Merc 280C      17.8 123
Ferrari Dino   19.7 175

En el código anterior solo pedimos las líneas en las cuales cyl == 6 y las columnas mpg y hp . Podría obtener el mismo resultado usando [] con el siguiente código:

mtcars[mtcars$cyl == 6, c("mpg", "hp")]

transformar

La función transform() es una función de conveniencia para cambiar columnas dentro de un data.frame . Por ejemplo, el siguiente código agrega otra columna llamada mpg2 con el resultado de mpg^2 a mtcars data.frame :

mtcars <- transform(mtcars, mpg2 = mpg^2)

con y dentro de

Tanto with() como within() permiten evaluar expresiones dentro del entorno data.frame , lo que permite una sintaxis algo más limpia, lo que le ahorra el uso de $ o [] .

Por ejemplo, si desea crear, cambiar y / o eliminar varias columnas en el airquality data.frame :

aq <- within(airquality, {     
    lOzone <- log(Ozone) # creates new column
    Month <- factor(month.abb[Month]) # changes Month Column
    cTemp <- round((Temp - 32) * 5/9, 1) # creates new column
    S.cT <- Solar.R / cTemp  # creates new column
    rm(Day, Temp) # removes columns
})

Introducción

Los marcos de datos son probablemente la estructura de datos que más utilizará en sus análisis. Un marco de datos es un tipo especial de lista que almacena vectores de longitud diferente de diferentes clases. Puede crear marcos de datos utilizando la función data.frame . El siguiente ejemplo muestra esto combinando un vector de caracteres y números en un marco de datos. Utiliza el operador : que creará un vector que contiene todos los números enteros del 1 al 3.

df1 <- data.frame(x = 1:3, y = c("a", "b", "c"))
df1
##   x y
## 1 1 a
## 2 2 b
## 3 3 c
class(df1)
## [1] "data.frame"

Los objetos de marco de datos no se imprimen entre comillas, por lo que la clase de las columnas no siempre es obvia.

df2 <- data.frame(x = c("1", "2", "3"), y = c("a", "b", "c"))
df2
##   x y
## 1 1 a
## 2 2 b
## 3 3 c

Sin más investigación, las columnas "x" en df1 y df2 no se pueden diferenciar. La función str se puede usar para describir objetos con más detalle que la clase.

str(df1)
## 'data.frame':    3 obs. of  2 variables:
##  $ x: int  1 2 3
##  $ y: Factor w/ 3 levels "a","b","c": 1 2 3
str(df2)
## 'data.frame':    3 obs. of  2 variables:
##  $ x: Factor w/ 3 levels "1","2","3": 1 2 3
##  $ y: Factor w/ 3 levels "a","b","c": 1 2 3

Aquí se ve que df1 es un data.frame y tiene 3 observaciones de 2 variables, "x" e "y". Luego se le dice que "x" tiene el tipo de datos entero (no es importante para esta clase, pero para nuestros propósitos se comporta como un número) y que "y" es un factor con tres niveles (otra clase de datos que no estamos discutiendo). Es importante tener en cuenta que, de forma predeterminada, los marcos de datos obligan a los personajes a los factores. El comportamiento predeterminado se puede cambiar con el parámetro stringsAsFactors :

df3 <- data.frame(x = 1:3, y = c("a", "b", "c"), stringsAsFactors = FALSE)
str(df3)
## 'data.frame':    3 obs. of  2 variables:
##  $ x: int  1 2 3
##  $ y: chr  "a" "b" "c"

Ahora la columna "y" es un carácter. Como se mencionó anteriormente, cada "columna" de un marco de datos debe tener la misma longitud. Intentar crear un data.frame a partir de vectores con diferentes longitudes dará como resultado un error. (Intente ejecutar data.frame(x = 1:3, y = 1:4) para ver el error resultante).

Como casos de prueba para marcos de datos, R proporciona algunos datos de forma predeterminada. Uno de ellos es el iris, cargado de la siguiente manera:

mydataframe <- iris
str(mydataframe)

Convierta los datos almacenados en una lista en un solo marco de datos usando do.call

Si tiene sus datos almacenados en una lista y desea convertir esta lista en un marco de datos, la función do.call es una forma fácil de lograrlo. Sin embargo, es importante que todos los elementos de la lista tengan la misma longitud para evitar el reciclaje involuntario de valores.

dataList  <- list(1:3,4:6,7:9)  
dataList
# [[1]]
# [1] 1 2 3
#
# [[2]]
# [1] 4 5 6
#
# [[3]]
# [1] 7 8 9

dataframe <- data.frame(do.call(rbind, dataList))
dataframe
#   X1 X2 X3
# 1  1  2  3
# 2  4  5  6
# 3  7  8  9 

También funciona si su lista se compone de marcos de datos en sí.

dataframeList  <- list(data.frame(a = 1:2, b = 1:2, c = 1:2), 
                       data.frame(a = 3:4, b = 3:4, c = 3:4))
dataframeList
# [[1]]
#   a b c
# 1 1 1 1
# 2 2 2 2

# [[2]]
#   a b c
# 1 3 3 3
# 2 4 4 4

dataframe      <- do.call(rbind, dataframeList)
dataframe
#   a b c
# 1 1 1 1
# 2 2 2 2
# 3 3 3 3
# 4 4 4 4

Convertir todas las columnas de un data.frame a clase de caracteres

Una tarea común es convertir todas las columnas de un data.frame en una clase de caracteres para facilitar la manipulación, como en el caso de enviar data.frames a un RDBMS o fusionar data.frames que contienen factores donde los niveles pueden diferir entre los datos de entrada. .

El mejor momento para hacerlo es cuando los datos se leen en - casi todos los métodos de entrada que crear tramas de datos tienen una opciones stringsAsFactors que se pueden ajustar a FALSE .

Si los datos ya se han creado, las columnas de factores se pueden convertir en columnas de caracteres como se muestra a continuación.

bob <- data.frame(jobs = c("scientist", "analyst"), 
                  pay  = c(160000, 100000), age = c(30, 25))
str(bob)
'data.frame':    2 obs. of  3 variables:
 $ jobs: Factor w/ 2 levels "analyst","scientist": 2 1
 $ pay : num  160000 100000
 $ age : num  30 25
# Convert *all columns* to character
bob[] <- lapply(bob, as.character)
str(bob)
    'data.frame':    2 obs. of  3 variables:
 $ jobs: chr  "scientist" "analyst"
 $ pay : chr  "160000" "1e+05"
 $ age : chr  "30" "25"
# Convert only factor columns to character
bob[] <- lapply(bob, function(x) {
    if is.factor(x) x <- as.character(x)
    return(x)
})

Subconjunto de filas por valores de columna

Las funciones integradas pueden subcontratar rows con columns que cumplen con las condiciones.

df <- data.frame(item = c(1:10),
                 price_Elasticity = c(-0.57667, 0.03205, -0.04904, 0.10342, 0.04029, 
                                       0.0742, 0.1669, 0.0313, 0.22204, 0.06158),
                 total_Margin = c(-145062, 98671, 20576, -56382, 207623, 43463, 1235, 
                                   34521, 146553, -74516))

Para encontrar rows con price_Elasticity > 0 :

df[df$price_Elasticity > 0, ]

   item price_Elasticity total_Margin
2     2          0.03205        98671
4     4          0.10342       -56382
5     5          0.04029       207623
6     6          0.07420        43463
7     7          0.16690         1235
8     8          0.03130        34521
9     9          0.22204       146553
10   10          0.06158       -74516

subconjunto basado en price_Elasticity > 0 y total_Margin > 0 :

df[df$price_Elasticity > 0 & df$total_Margin > 0, ]

  item price_Elasticity total_Margin
2    2          0.03205        98671
5    5          0.04029       207623
6    6          0.07420        43463
7    7          0.16690         1235
8    8          0.03130        34521
9    9          0.22204       146553


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow