vectores programacion funciones filas eliminar ejemplos disponibles datos data contar bases r metadata data-management

programacion - funciones en r



¿Cómo crear, estructurar, mantener y actualizar libros de códigos de datos en R? (4)

Cómo hago esto es un poco diferente y notablemente menos técnico. Generalmente, sigo el principio rector de que si el texto no está diseñado para ser significativo para la computadora y solo para los humanos, entonces pertenece a los comentarios en el código fuente.

Esto puede parecer más bien "de baja tecnología" pero hay algunas buenas razones para hacer esto:

  • Cuando alguien más recoja su código en el futuro, es intuitivo que los comentarios están destinados inequívocamente para que los lean. Los parámetros establecidos en lugares inusuales dentro de las estructuras de datos pueden no ser obvios para el futuro usuario.
  • Mantener un registro de los parámetros establecidos dentro de los objetos abstractos requiere un poco de disciplina. La creación de comentarios en código también requiere disciplina, pero la ausencia del comentario es inmediatamente obvia. Si las descripciones se llevan como parte del objeto, echar un vistazo al código no lo hace obvio. El código se vuelve menos "alfabetizado" en el sentido de "programación alfabetizada" de la palabra.
  • Llevar descripciones de los datos dentro del objeto de datos puede resultar fácilmente en descripciones que son incorrectas. Esto puede suceder si, por ejemplo, una columna que contiene una medida en kg se multiplica por 2.2 para convertir las unidades a libras. Sería muy fácil pasar por alto la necesidad de actualizar los metadatos.

Obviamente, hay algunas ventajas reales de llevar metadatos junto con los objetos. Y si su flujo de trabajo hace que los puntos anteriores sean menos pertinentes, entonces puede tener mucho sentido crear un adjunto de metadatos a su estructura de datos. Mi intención era solo compartir algunas razones por las que se podría considerar un enfoque basado en comentarios de "baja tecnología".

En el interés de la replicación, me gusta mantener un libro de códigos con metadatos para cada marco de datos. Un libro de códigos de datos es:

una lista escrita o computarizada que proporciona una descripción clara y completa de las variables que se incluirán en la base de datos. Marczyk et al ( 2010 )

Me gusta documentar los siguientes atributos de una variable:

  • nombre
  • descripción (etiqueta, formato, escala, etc)
  • fuente (por ejemplo, banco mundial)
  • medios de origen (URL y fecha de acceso, CD e ISBN, o lo que sea)
  • nombre de archivo de los datos de origen en el disco (ayuda cuando se combinan libros de códigos)
  • notas

Por ejemplo, esto es lo que estoy implementando para documentar las variables en el marco de datos mydata1 con 8 variables:

code.book.mydata1 <- data.frame(variable.name=c(names(mydata1)), label=c("Label 1", "State name", "Personal identifier", "Income per capita, thousand of US$, constant year 2000 prices", "Unique id", "Calendar year", "blah", "bah"), source=rep("unknown",length(mydata1)), source_media=rep("unknown",length(mydata1)), filename = rep("unknown",length(mydata1)), notes = rep("unknown",length(mydata1)) )

Escribo un libro de códigos diferente para cada conjunto de datos que leo. Cuando fusiono marcos de datos, también fusionaré los aspectos relevantes de su libro de códigos asociado, para documentar la base de datos final. Lo hago esencialmente copiando el código anterior y cambiando los argumentos.


La función comment() podría ser útil aquí. Puede establecer y consultar un atributo de comentario en un objeto, pero tiene la ventaja de otros atributos normales de no imprimirse.

dat <- data.frame(A = 1:5, B = 1:5, C = 1:5) comment(dat$A) <- "Label 1" comment(dat$B) <- "Label 2" comment(dat$C) <- "Label 3" comment(dat) <- "data source is, sampled on 1-Jan-2011"

lo que da:

> dat A B C 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 5 5 5 5 > dat$A [1] 1 2 3 4 5 > comment(dat$A) [1] "Label 1" > comment(dat) [1] "data source is, sampled on 1-Jan-2011"

Ejemplo de fusión:

> dat2 <- data.frame(D = 1:5) > comment(dat2$D) <- "Label 4" > dat3 <- cbind(dat, dat2) > comment(dat3$D) [1] "Label 4"

pero eso pierde el comentario en dat() :

> comment(dat3) NULL

por lo que ese tipo de operaciones necesitarían un manejo explícito. Para hacer realmente lo que quiere, es probable que tenga que escribir versiones especiales de las funciones que utiliza que mantienen los comentarios / metadatos durante las operaciones de extracción / fusión. De forma alternativa, es posible que desee crear sus propias clases de objetos: digamos como una lista con un marco de datos y otros componentes que contienen los metadatos. Luego escriba los métodos para las funciones que desea que conserven los metadatos.

Un ejemplo en este sentido es el paquete zoo que genera un objeto de lista para una serie de tiempo con componentes adicionales que contienen el orden y la información de fecha / hora, etc., pero aún funciona como un objeto normal desde el punto de vista del subconjunto, etc. porque los autores han proporcionado Métodos para funciones como [ etc.


Podría agregar cualquier atributo especial a cualquier objeto R con la función attr . P.ej:

x <- cars attr(x,"source") <- "Ezekiel, M. (1930) _Methods of Correlation Analysis_. Wiley."

Y ver el atributo dado en la estructura del objeto:

> str(x) ''data.frame'': 50 obs. of 2 variables: $ speed: num 4 4 7 7 8 9 10 10 10 11 ... $ dist : num 2 10 4 22 16 10 18 26 34 17 ... - attr(*, "source")= chr "Ezekiel, M. (1930) _Methods of Correlation Analysis_. Wiley."

Y también podría cargar el atributo especificado con la misma función attr :

> attr(x, "source") [1] "Ezekiel, M. (1930) _Methods of Correlation Analysis_. Wiley."

Si solo agrega nuevos casos a su marco de datos, el atributo dado no se verá afectado (ver: str(rbind(x,x)) mientras que al alterar la estructura se borrarán los atributos dados (vea: str(cbind(x,x)) ).

ACTUALIZACIÓN: basado en comentarios.

Si desea enumerar todos los atributos no estándar, verifique lo siguiente:

setdiff(names(attributes(x)),c("names","row.names","class"))

Esto mostrará una lista de todos los atributos no estándar (los estándares son: nombres, row.names, clase en marcos de datos).

En base a eso, podría escribir una función corta para enumerar todos los atributos no estándar y también los valores. Lo siguiente funciona, aunque no de forma ordenada ... Podría mejorarlo y crear una función :)

Primero, defina los atributos uniqe (= no estándar):

uniqueattrs <- setdiff(names(attributes(x)),c("names","row.names","class"))

Y haz una matriz que contendrá los nombres y valores:

attribs <- matrix(0,0,2)

Recorra los atributos no estándar y guarde en la matriz los nombres y valores:

for (i in 1:length(uniqueattrs)) { attribs <- rbind(attribs, c(uniqueattrs[i], attr(x,uniqueattrs[i]))) }

Convierta la matriz en un marco de datos y nombre las columnas:

attribs <- as.data.frame(attribs) names(attribs) <- c(''name'', ''value'')

Y guardar en cualquier formato, ej .:

write.csv(attribs, ''foo.csv'')

Para su pregunta sobre las etiquetas de variables, verifique la función read.spss del paquete foráneo , ya que hace exactamente lo que necesita: guarda las etiquetas de valor en la sección de atributos. La idea principal es que un attr podría ser un marco de datos u otro objeto, por lo que no necesita crear un "attr" único para cada variable, sino crear solo uno (por ejemplo, con el nombre de "etiquetas variables") y guardar toda la información allí. . Puedes llamar como: attr(x, "variable.labels")[''foo''] donde ''foo'' significa el nombre de la variable requerida. Pero compruebe la función citada anteriormente y también los atributos de los marcos de datos importados para obtener más detalles.

¡Espero que estos puedan ayudarte a escribir las funciones requeridas de una manera mucho mejor que lo que he probado anteriormente! :)


Una versión más avanzada sería utilizar clases S4. Por ejemplo, en bioconductor, ExpressionSet se usa para almacenar datos de micromatrices con sus metadatos experimentales asociados.

El objeto MIAME descrito en la ExpressionSet , se ve muy similar a lo que está después:

experimentData <- new("MIAME", name = "Pierre Fermat", lab = "Francis Galton Lab", contact = "[email protected]", title = "Smoking-Cancer Experiment", abstract = "An example ExpressionSet", url = "www.lab.not.exist", other = list(notes = "Created from text files"))