2

I am wanting to split a character vector column into multiple rows (of the same dataframe), while maintaining other columns (keep) in this reproducible example:

dat<-structure(list(ID = c("E87", "E42", "E39", "E16,E17,E18", "E760,E761,E762"), keep = 1:5), row.names = c(NA, 5L), class = "data.frame")
> dat
              ID keep
1            E87    1
2            E42    2
3            E39    3
4    E16,E17,E18    4
5 E760,E761,E762    5

Of course we can split ID with strsplit, but the output is in list format (which is always confusing to me for some reason), and without the column keep

strsplit(dat$ID, ",")

[[1]]
[1] "E87"

[[2]]
[1] "E42"

[[3]]
[1] "E39"

[[4]]
[1] "E16"  " E17" " E18"

[[5]]
[1] "E760" "E761" "E762"

Using unlist I can get this output back into a vector, but now the order will surely be lost to be able to recombine keep with ID.

unlist(strsplit(dat$ID, ","))

[1] "E87"  "E42"  "E39"  "E16"  " E17" " E18" "E760" "E761" "E762"

Any thoughts as to how I might get this output:

> dat
              ID keep
1            E87    1
2            E42    2
3            E39    3
4            E16    4
5            E17    4
6            E18    4
7            E760   5
8            E761   5
9            E762   5
Dylan_Gomes
  • 2,066
  • 14
  • 29

1 Answers1

0

An easier option is separate_rows

library(tidyr)
separate_rows(dat, ID)
#    ID keep
#1  E87    1
#2  E42    2
#3  E39    3
#4  E16    4
#5  E17    4
#6  E18    4
#7 E760    5
#8 E761    5
#9 E762    5

Or using the OP's method, after splitting the 'ID', name it with 'keep' column and then stack it to a two column data.frame

stack(setNames(strsplit(dat$ID, ","), dat$keep))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Works perfectly, thanks! I should have clarified that I have multiple separators in the full dataset, but that is easily fixed with the `sep` argument in your first example: `separate_rows(dat, ID, sep="(,|;)")` if both "," and ";" are separators (for example), or as `stack(setNames(strsplit(dat$ID, "(,|;)"), dat$keep))` in your second example. – Dylan_Gomes Dec 02 '19 at 23:20
  • 1
    @Dylan_Gomes Yes, with multiple separators, `sep="[,;]"` – akrun Dec 02 '19 at 23:21
  • 1
    I am waiting for SO to let me accept. Your answer was too fast ;) – Dylan_Gomes Dec 02 '19 at 23:23