es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cambiar la longitud de un objeto utilizando la función get() en R.

Estoy escribiendo una función para analizar archivos .csv en un directorio en mi disco duro, utilizando una serie de bucles for y while (Sé que los bucles for no son populares en R, pero son buenos para lo que necesito).

La función crea varios data frames y realiza acciones en cada uno de ellos antes de sobrescribirlos y pasar al siguiente archivo en el directorio para repetir la acción.

La parte del código que no funciona hasta ahora es la creación de una matriz a partir de vectores tomados de los archivos de datos que se están analizando. A continuación se muestra una versión simplificada del código:

data1 <- seq(1, 10, 1)
data2 <- seq(1, 7, 1)
data3 <- seq(1, 5, 1)

n <- max(length(data1), length(data2), length(data3))

k <- c(1, 2, 3)

for(a in k){

  if(a == 1){

    length(get(paste("data", a, sep = ""))) <- n
    data_matrix <- get(paste("data", a, sep = ""))

  }else{

    while(exists(paste("data", a, sep = ""))){

      length(get(paste("data", a, sep = ""))) <- n
      data_matrix <- cbind(data_matrix, get(paste("data", a, sep = "")))

    }

  }

} 

La naturaleza de mis datos es que la longitud de las columnas en mis conjuntos de datos varía con cada recolección de datos, por lo que he adaptado una técnica encontrada en esta publicación que trata de utilizar cbind para unir objetos de diferentes longitudes sin replicar los datos dentro de los objetos más pequeños.

El problema que tengo al intentar implementar este código es que obtengo el mensaje de error:

Error in length(get(paste(“data”, a, sep = “”))) <- n :
target of assignment expands to non-language object

Supongo que el problema es que la función get() no puede utilizarse para seleccionar elementos en el entorno global y modificarlos de esta manera.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución

    El problema en el código es que no se puede asignar un valor al resultado de la llamada a la función get, ya que no es una referencia al objeto original en el Entorno Global.

    Aquí hay una versión modificada del código que crea una lista de marcos de datos, cada uno con la misma longitud, y luego los combina usando cbind.fill del paquete rowr:

    library(rowr)
    
    file_list <- list.files(path = "/ruta/al/directorio", pattern = "\\.csv$", full.names = TRUE)
    
    df_list <- list()
    
    for (i in seq_along(file_list)) {
      # leer el archivo csv como un marco de datos
      df <- read.csv(file_list[i])
    
      # establecer la longitud de todas las columnas para que sean iguales
      max_len <- max(nrow(df_list), nrow(df))
      if (max_len > nrow(df)) {
        df <- rbind(df, data.frame(matrix(NA, nrow = max_len - nrow(df), ncol = ncol(df))))
      } else if (max_len > nrow(df_list)) {
        df_list[[i - 1]] <- rbind(df_list[[i - 1]], data.frame(matrix(NA, nrow = max_len - nrow(df_list[[i - 1]]), ncol = ncol(df_list[[i - 1]]))))
      }
    
      # añadir el marco de datos a la lista
      df_list[[i]] <- df
    }
    
    # combinar todos los marcos de datos usando cbind.fill
    result <- do.call(cbind.fill, df_list)
    

    Este código lee todos los archivos csv en un directorio y crea una lista de marcos de datos, cada uno con la misma longitud (igual a la longitud máxima de todos los marcos de datos). Si un marco de datos es más corto que la longitud máxima, se completa con valores NA.

    Finalmente, la función cbind.fill se utiliza para combinar todos los marcos de datos en uno solo, con los valores faltantes rellenados con NA. Este enfoque evita la necesidad de bucles y maneja conjuntos de datos de longitud variable de manera más eficiente.

Comments are closed.