Agregar una nueva columna a cada elemento en una lista de tablas o marcos de datos

Tengo una lista de archivos. También tengo una lista de “nombres” que substr() de los nombres de archivo reales de estos archivos. Me gustaría agregar una nueva columna a cada uno de los archivos en la lista. Esta columna contendrá el elemento correspondiente en “nombres” repetido veces el número de filas en el archivo.

Por ejemplo:

 df1 <- data.frame(x = 1:3, y=letters[1:3]) df2 <- data.frame(x = 4:6, y=letters[4:6]) filelist <- list(df1,df2) ID <- c("1A","IB") 

Pseudocódigo

  for( i in length(filelist)){ filelist[i]$SampleID <- rep(ID[i],nrow(filelist[i]) } 

// básicamente crea una nueva columna en cada uno de los marcos de datos en la lista de archivos, y llena la columna con valores repetidos correspondientes de ID

mi salida debería ser como:

filelist[1] debería ser:

  xy SAmpleID 1 1 a 1A 2 2 b 1A 3 3 c 1A 

fileList[2]

  xy SampleID 1 4 d IB 2 5 e IB 3 6 f IB 

y así…..

Cualquier idea de cómo se podría hacer.

Una solución alternativa es usar cbind, y aprovechar el hecho de que R recylce los valores de un vector más corto.

Por ejemplo

 x <- df2 # from above cbind(x, NewColumn="Singleton") # xy NewColumn # 1 4 d Singleton # 2 5 e Singleton # 3 6 f Singleton 

No hay necesidad de usar rep . R lo hace por ti.

Por lo tanto, podría poner cbind(filelist[[i]], ID[[i]]) en su for loop o como lo señaló @Sven, puede usar mapply :

 filelist <- mapply(cbind, filelist, "SampleID"=ID, SIMPLIFY=F) 

Esta es una versión corregida de su ciclo:

 for( i in seq_along(filelist)){ filelist[[i]]$SampleID <- rep(ID[i],nrow(filelist[[i]])) } 

Hubo 3 problemas:

  • A final ) faltaba después del comando en el cuerpo.
  • Los elementos de las listas son accedidos por [[ , no por [ . [ devuelve una lista de longitud uno. [[ devuelve el elemento solo.
  • length(filelist) es solo un valor, por lo que el ciclo se ejecuta solo para el último elemento de la lista. Lo reemplacé con seq_along(filelist) .

Un enfoque más eficiente es utilizar mapply para la tarea:

 mapply(function(x, y) "[<-"(x, "SampleID", value = y) , filelist, ID, SIMPLIFY = FALSE) 

Una manera complicada:

 library(plyr) names(filelist) <- ID result <- ldply(filelist, data.frame) 

Este trabajó para mí:

Crea una nueva columna para cada dataframe en una lista; rellene los valores de la nueva columna según la columna existente. (En su caso IDs).

Ejemplo:

 # Create dummy data df1<-data.frame(a = c(1,2,3)) df2<-data.frame(a = c(5,6,7)) # Create a list l<-list(df1, df2) > l [[1]] a 1 1 2 2 3 3 [[2]] a 1 5 2 6 3 7 # add new column 'b' # create 'b' values based on column 'a' l2<-lapply(l, function(x) cbind(x, b = x$a*4)) 

Resultados en:

 > l2 [[1]] ab 1 1 4 2 2 8 3 3 12 [[2]] ab 1 5 20 2 6 24 3 7 28 

En tu caso, algo así como:

 filelist<-lapply(filelist, function(x) cbind(x, b = x$SampleID))