Lime
Lime

Reputation: 756

Mutate new column with unique values for each list

I have a list here, and I wish to mutate a new column with unique values for each list relative to the mutation. For example, I want to mutate a column named ID as n >= 1.

Naturally, on a dataframe I would do this:

dat %>% mutate(id = row_number())

For a list, I would do this:

dat%>% map(~ mutate(., ID = row_number()))

And I would get an output likeso:

dat <- list(data.frame(x=c("a", "b" ,"c", "d", "e" ,"f" ,"g") ), data.frame(y=c("p", "lk", "n", "m", "g", "f", "t")))

[[1]]
  x id
1 a  1
2 b  2
3 c  3
4 d  4
5 e  5
6 f  6
7 g  7

[[2]]
   y id
1  p  1
2 lk  2
3  n  3
4  m  4
5  g  5
6  f  6
7  t  7

Though, how would I mutate a new column ID such that the row number continues from the first list.

Expected output:

[[1]]
  x id
1 a  1
2 b  2
3 c  3
4 d  4
5 e  5
6 f  6
7 g  7

[[2]]
   y id
1  p  8
2 lk  9
3  n  10
4  m  11
5  g  12
6  f  13
7  t  14

Upvotes: 1

Views: 875

Answers (1)

akrun
akrun

Reputation: 887691

An option is to bind them into a single dataset, create the 'id' with row_number(), split by 'grp', loop over the list and remove any columns that have all NA values

library(dplyr)
library(purrr)
dat %>% 
  bind_rows(.id = 'grp') %>%
  mutate(id = row_number()) %>% 
  group_split(grp) %>%
  map(~ .x %>%
          select(where(~ any(!is.na(.))), -grp))

-output

#[[1]]
# A tibble: 7 x 2
#  x        id
#  <chr> <int>
#1 a         1
#2 b         2
#3 c         3
#4 d         4
#5 e         5
#6 f         6
#7 g         7

#[[2]]
# A tibble: 7 x 2
#  y        id
#  <chr> <int>
#1 p         8
#2 lk        9
#3 n        10
#4 m        11
#5 g        12
#6 f        13
#7 t        14

Or an easier approach is to unlist (assuming single column), get the sequence, add a new column with map2

map2(dat, relist(seq_along(unlist(dat)), skeleton = dat),
      ~ .x %>% mutate(id = .y))

Or using a for loop

dat[[1]]$id <- seq_len(nrow(dat[[1]]))
for(i in seq_along(dat)[-1]) dat[[i]]$id <- 
   seq(tail(dat[[i-1]]$id, 1) + 1, length.out = nrow(dat[[i]]), by = 1)

Upvotes: 1

Related Questions