0

I have a column in a data frame like so:

D0.5
A4
C1.3
B2.0

I want to be able to split the column so that the first entry (which is always a single character) is separated from the rest of the entry (which is always numeric, but is of different lengths depending on the entry)

I want to do basically exactly this except after the first entry instead of the 5th and in R instead of php.

split string after x characters

Community
  • 1
  • 1
User247365
  • 665
  • 2
  • 11
  • 27

2 Answers2

4

You can use substring

x <- c("D0.5", "A4", "C1.3", "B2.0")

substring(x, 1, 1)

[1] "D" "A" "C" "B"

To get only the numeric part:

as.numeric(substring(x, 2, nchar(x)))

[1] 0.5 4.0 1.3 2.0

Or using stringi:

as.numeric(stringi::stri_sub(x, 2))

and using stringr:

as.numeric(stringr::str_sub(x, 2))

For both stringi and stringr, 2 represents the starting position. You can include the end position if you want to, else it is the last character by default.

Sumedh
  • 4,835
  • 2
  • 17
  • 32
  • And the numeric part? – Frank Aug 02 '16 at 15:57
  • You should extract 0.5 etc, presumably as a number, not a string. – Frank Aug 02 '16 at 15:58
  • To add to your solution, you could do something like the following to put it into a data frame: `data.frame(cbind(Letter=str_sub(x, 1, 1), Number=str_sub(x, 2)))` (where `x` is a vector of input). – steveb Aug 02 '16 at 16:11
  • @steveb, thanks! But I think it would just be easier to assign individual results in a df or use your suggestion without`cbind`. `cbind` will convert the columns into factors – Sumedh Aug 02 '16 at 17:05
  • @Sumedh Understood. The following would work better than what I originally suggested: `data.frame(Letter=str_sub(x, 1, 1), Number=as.numeric(str_sub(x, 2)), stringsAsFactors = FALSE)` (or some variant of this). – steveb Aug 02 '16 at 17:08
1

We can use sub

as.numeric(sub("^.(.*)", "\\1", v1))
#[1] 0.5 4.0 1.3 2.0

Or

library(tidyr)
extract_numeric(v1)
#[1] 0.5 4.0 1.3 2.0

data

v1 <- c("D0.5", "A4", "C1.3", "B2.0")
akrun
  • 874,273
  • 37
  • 540
  • 662