2017-10-20 17 views
0

j'ai de nombreux dataframes dans mon environnement:ligne lier plusieurs dataframes et ajouter le nom de dataframe d'origine dans la colonne

x1 <- structure(list(time = structure(c(1327241343, 1327327803, 1327414263 
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), x1 = c(22.5, 
12, 0)), .Names = c("time", "x1"), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -3L)) 

x2 <- structure(list(time = structure(c(1326636543, 1326636603, 1326636663 
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), x2 = c(8, 
6, 1)), .Names = c("time", "x2"), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -3L)) 

x3 <- structure(list(time = structure(numeric(0), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), x3 = numeric(0)), .Names = c("time", 
"x1"), class = c("tbl_df", "tbl", "data.frame"), row.names = integer(0)) 

##----------------------------------------------------------------------------- 
## PREVIEW 
##----------------------------------------------------------------------------- 
> knitr::kable(x1) 

|time    | x1| 
|:-------------------|----:| 
|2012-01-22 14:09:03 | 22.5| 
|2012-01-23 14:10:03 | 12.0| 
|2012-01-24 14:11:03 | 0.0| 

> knitr::kable(x2) 

|time    | x2| 
|:-------------------|--:| 
|2012-01-15 14:09:03 | 8| 
|2012-01-15 14:10:03 | 6| 
|2012-01-15 14:11:03 | 1| 

> knitr::kable(x3) 

|time | x1| 
|:----|--:| 

Notez que x3 est une trame de données vide, car cela reflète mon scénario. J'essaie d'obtenir la ligne suivante binded simple dataframe:

x.all <- structure(list(time = structure(c(1327241343, 1327327803, 1327414263, 
1326636543, 1326636603, 1326636663), class = c("POSIXct", "POSIXt" 
), tzone = "UTC"), x = c(22.5, 12, 0, 8, 6, 1), which = c("x1", 
"x1", "x1", "x2", "x2", "x2")), .Names = c("time", "x", "which" 
), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-6L)) 

##----------------------------------------------------------------------------- 
## PREVIEW 
##----------------------------------------------------------------------------- 
> knitr::kable(x.all) 

|time    | x|which | 
|:-------------------|----:|:-----| 
|2012-01-22 14:09:03 | 22.5|x1 | 
|2012-01-23 14:10:03 | 12.0|x1 | 
|2012-01-24 14:11:03 | 0.0|x1 | 
|2012-01-15 14:09:03 | 8.0|x2 | 
|2012-01-15 14:10:03 | 6.0|x2 | 
|2012-01-15 14:11:03 | 1.0|x2 | 

Je sais comment faire un par un. Cependant, avec plus de 100 dataframes et je cherche un moyen de le faire efficacement (chaque dataframe contient 2 colonnes et> 500.000 lignes).

Merci.

Répondre

1

Cela devrait fonctionner pour vous, en utilisant tidyverse. Utilisez get pour récupérer les données par nom.

listofdf <- paste0("x", 1:3) 
# "x1" "x2" "x3" 

library(tidyverse) 
map_df(listofdf, ~get(.x) %>% setNames(c("time","x")), .id="which") %>% 
    mutate(which = paste0("x", which)) %>% 
    select(time, x, which) 

# # A tibble: 6 x 3 
       # time  x which 
       # <dttm> <dbl> <chr> 
# 1 2012-01-22 14:09:03 22.5 x1 
# 2 2012-01-23 14:10:03 12.0 x1 
# 3 2012-01-24 14:11:03 0.0 x1 
# 4 2012-01-15 14:09:03 8.0 x2 
# 5 2012-01-15 14:10:03 6.0 x2 
# 6 2012-01-15 14:11:03 1.0 x2 

Modifier Travailler avec des données qui ne sont pas toujours commencer même modèle

Vous devez faire 2 modifications

Obtenir des données dans votre environnement R avec ls()

listofdf <- ls() 
# "x1" "x2" "x3" 

Obtenir des identifiants avec mutate(which = listofdf[as.integer(which)]) au lieu de mutate(which = paste0("x", which))

map_df(listofdf, ~get(.x) %>% setNames(c("time","x")), .id="which") %>% 
    mutate(which = listofdf[as.integer(which)]) %>% # 2nd change 
    select(time, x, which) 
+0

Merci. Cela fonctionne presque. Pouvez-vous éditer pour le cas où la variable x ne peut pas être construite à partir d'un motif (c'est-à-dire 'paste0 (" x ", 1: 3)')? Heureux de l'accepter comme une réponse. –

+0

'listofdf <- c (" x1 "," x2 "," x3 ")'? –