1

Suppose I have a data frame with eight digit numbers, each corresponding to one

x <- data.frame(y = c(12345678, 87654321))

I want 8 columns such that each column corresponds to one number i.e.

   y1   y2   y3   y4   y5   y6   y7   y8
    1    2    3    4    5    6    7    8     
    8    7    6    5    4    3    2    1   

(The columns don't have to be named y1 to y8, I'm just naming them that way for illustrative purposes)

Normally in R, I would use separate, but here there is no clear separator. How can I do this?

wwl
  • 2,025
  • 2
  • 30
  • 51
  • This was marked as a duplicate but it is different. The so-called duplicate had separators but this one does not. – G. Grothendieck Aug 24 '18 at 11:08
  • @G.Grothendieck `""` is the separator here. There are at least 2 solution from that link which fits as an answer here and gives the expected output. – Ronak Shah Aug 25 '18 at 01:17
  • `str_split_fixed(x$y, "", 8);` `do.call("rbind", strsplit(as.character(x$y),''));` `do.call(rbind, str_split(x$y, ''))` ` – Ronak Shah Aug 25 '18 at 01:23
  • Possible duplicate https://stackoverflow.com/questions/4350440/split-data-frame-string-column-into-multiple-columns – Ronak Shah Aug 25 '18 at 01:23
  • This one is specifically mentions a preference for separate and that one does not. – G. Grothendieck Aug 25 '18 at 01:28

4 Answers4

3

separate can accept column positions in the sep argument. This acts as if there were separators after columns 1, 2, ..., 7.

library(tidyr)

separate(x, y, into = paste0("y", 1:8), sep = 1:7)

giving:

  y1 y2 y3 y4 y5 y6 y7 y8
1  1  2  3  4  5  6  7  8
2  8  7  6  5  4  3  2  1
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
1

Here is a base R option using strsplit

as.data.frame(t(apply(x, 1, function(x) unlist(strsplit(as.character(x), "")))))
#  V1 V2 V3 V4 V5 V6 V7 V8
#1  1  2  3  4  5  6  7  8
#2  8  7  6  5  4  3  2  1

Or a tidyverse option

library(tidyverse)
x %>%
    rowid_to_column("row") %>%
    mutate(y = strsplit(as.character(y), "")) %>%
    unnest() %>%
    group_by(row) %>%
    mutate(var = paste0("y", 1:n())) %>%
    spread(var, y) %>%
    ungroup() %>%
    select(-row)
#  y1    y2    y3    y4    y5    y6    y7    y8
#  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 1     2     3     4     5     6     7     8
#2 8     7     6     5     4     3     2     1
Maurits Evers
  • 49,617
  • 4
  • 47
  • 68
0

Another R base alternative

> data.frame(do.call(rbind, strsplit(as.character(x$y), "")))
  X1 X2 X3 X4 X5 X6 X7 X8
1  1  2  3  4  5  6  7  8
2  8  7  6  5  4  3  2  1
Jilber Urbina
  • 58,147
  • 10
  • 114
  • 138
0

Solution from stringr

data.frame(stringr::str_split_fixed(x$y, "", 8))
  X1 X2 X3 X4 X5 X6 X7 X8
1  1  2  3  4  5  6  7  8
2  8  7  6  5  4  3  2  1
BENY
  • 317,841
  • 20
  • 164
  • 234