Consider this vector
names <- c("Jon", "Nancy")
And, a list of dataframes with the same length
listed_dfs <- list(tibble(X = sample(1:5),
Y = sample(1:5)),
tibble(X = sample(11:15),
Y = sample(11:15)))
I would like to add a new column in each of them with a name according to their position in the vector. Such that the desired output would be:
[[1]]
# A tibble: 5 x 3
X Y name
<int> <int> <chr>
1 4 1 Jon
2 2 5 Jon
3 5 2 Jon
4 3 4 Jon
5 1 3 Jon
[[2]]
# A tibble: 5 x 3
X Y name
<int> <int> <chr>
1 14 13 Nancy
2 11 14 Nancy
3 12 12 Nancy
4 15 11 Nancy
5 13 15 Nancy
I have tried imap and map without any results.
EDIT:
Okay, I managed to find a solution
imap(listed_dfs, ~ bind_cols(.x, name = names[.y]))
But I'm still open to other suggestions, if there are cleaner ways
CodePudding user response:
You could use map2
from purrr
:
map2(listed_dfs, names, ~ bind_cols(name = .y, .x))
[[1]]
# A tibble: 5 × 3
name X Y
<chr> <int> <int>
1 Jon 3 2
2 Jon 1 3
3 Jon 4 1
4 Jon 5 4
5 Jon 2 5
[[2]]
# A tibble: 5 × 3
name X Y
<chr> <int> <int>
1 Nancy 15 12
2 Nancy 13 14
3 Nancy 11 11
4 Nancy 14 13
5 Nancy 12 15
If your final goal is to bind them, you could directly use bind_rows(..., .id = 'name')
from dplyr
:
bind_rows(set_names(listed_dfs, names), .id = 'name')
# A tibble: 10 × 3
name X Y
<chr> <int> <int>
1 Jon 3 2
2 Jon 1 3
3 Jon 4 1
4 Jon 5 4
5 Jon 2 5
6 Nancy 15 12
7 Nancy 13 14
8 Nancy 11 11
9 Nancy 14 13
10 Nancy 12 15
CodePudding user response:
If you wish to use map
, I believe the syntax should be similar to lapply
. And the output would still be a list of tibbles.
library(tidyverse)
map(seq_along(names), ~ bind_cols(listed_dfs[[.x]], name = names[.x]))
[[1]]
# A tibble: 5 × 3
X Y name
<int> <int> <chr>
1 2 1 Jon
2 1 2 Jon
3 4 3 Jon
4 5 4 Jon
5 3 5 Jon
[[2]]
# A tibble: 5 × 3
X Y name
<int> <int> <chr>
1 12 14 Nancy
2 15 13 Nancy
3 11 11 Nancy
4 13 15 Nancy
5 14 12 Nancy