# [R] Taking diff of character vectors

Barry Rowlingson b.rowlingson at lancaster.ac.uk
Fri Mar 13 11:42:13 CET 2009

```2009/3/13 Sergey Goriatchev <sergeyg at gmail.com>:

> Say I have
> nm1 <- c(rep(1,10), rep(0,10))
> then I can do:
> diff(nm1)
> to see where I have shift in value
>
> but what if I have
> nm2 <- c(rep("SPZ8", 10), rep("SPX9", 10))
>
> how can I produce the same ouput as diff(nm1) does, that is zeros
> everywhere except for one place where SPZ8 changes to SPX9 (there
> should be 1 there)?
>
> What if I have a matrix of characters like that:
> nm3 <- c(rep("GLF9", 4), rep("GLF10", 16))
> matr <- cbind(nm2, nm3)
>
> How can I efficiently create two more columns that contain zeros
> everywhere except for place where there is shift in character values?

You could convert to "factor" and then to numeric:

> nm2 <- c(rep("SPZ8", 10), rep("SPX9", 10))

> diff(as.numeric(as.factor(nm2)))
[1]  0  0  0  0  0  0  0  0  0 -1  0  0  0  0  0  0  0  0  0

It might be that your character values should really be factors
anyway - check out some R docs on what factors are and what they can
do for you. That also means you might want your matrix to be a data
frame, since a matrix can't contain your character values and numeric
0/1 values. Data frames can! If you try it with a matrix you end up
getting character zeroes and minus ones:

> matr <- cbind(nm2, nm3)

> matr = cbind(matr,c(0,diff(as.numeric(as.factor(matr[,1])))))

> matr[8:12,]
nm2    nm3
[1,] "SPZ8" "GLF10" "0"
[2,] "SPZ8" "GLF10" "0"
[3,] "SPZ8" "GLF10" "0"
[4,] "SPX9" "GLF10" "-1"
[5,] "SPX9" "GLF10" "0"

Easier with factors in data frames:

> df=data.frame(nm2=as.factor(nm2),nm3=as.factor(nm3))

> df\$dnm2 = c(0,diff(as.numeric(df\$nm2)))
> df[8:12,]
nm2   nm3 dnm2
8  SPZ8 GLF10    0
9  SPZ8 GLF10    0
10 SPZ8 GLF10    0
11 SPX9 GLF10   -1
12 SPX9 GLF10    0

Barry

```