larkee
larkee

Reputation: 550

Merge two rows into one column in R

How can I merge two rows to one row like

...
type1,-2.427,-32.962,-61.097
type2,0.004276057,0.0015271631,-0.005192355
type1,-2.427,-32.962,-60.783
type2,0.0018325958,0.0033597588,-0.0021380284
...

to

type1,-2.427,-32.962,-61.097,type2,0.004276057,0.0015271631,-0.005192355
type1,-2.427,-32.962,-60.783,type2,0.0018325958,0.0033597588,-0.0021380284

or

-2.427,-32.962,-61.097,0.004276057,0.0015271631,-0.005192355
-2.427,-32.962,-60.783,0.0018325958,0.0033597588,-0.0021380284

in GNU R?

Upvotes: 1

Views: 1107

Answers (3)

Rich Scriven
Rich Scriven

Reputation: 99331

You could use split to split the data by type, and then use cbind to bring them together. The following method removes the first column ( [-1] ) from the result, and also uses MrFlick's data, dd,

> do.call(cbind, split(dd[-1], dd[[1]]))
#   type1.V2 type1.V3 type1.V4    type2.V2    type2.V3     type2.V4
# 1   -2.427  -32.962  -61.097 0.004276057 0.001527163 -0.005192355
# 3   -2.427  -32.962  -60.783 0.001832596 0.003359759 -0.002138028

On my machine, I have this as the fastest among the current three answers.

Upvotes: 1

A5C1D2H2I1M1N2O1R2T1
A5C1D2H2I1M1N2O1R2T1

Reputation: 193517

Here's an alternative using @MrFlick's sample data:

## Use `ave` to create an indicator variable
dd$ind <- with(dd, ave(as.numeric(V1), V1, FUN = seq_along))

## use `reshape` to "merge" your rows by indicator
reshape(dd, direction = "wide", idvar = "ind", timevar = "V1")
#   ind V2.type1 V3.type1 V4.type1    V2.type2    V3.type2     V4.type2
# 1   1   -2.427  -32.962  -61.097 0.004276057 0.001527163 -0.005192355
# 3   2   -2.427  -32.962  -60.783 0.001832596 0.003359759 -0.002138028

Upvotes: 2

MrFlick
MrFlick

Reputation: 206232

Do they always alternate 1/2? If so, you can just use basic indexing. Using this sample data.frame

dd<-structure(list(V1 = structure(c(1L, 2L, 1L, 2L), .Label = c("type1", 
"type2"), class = "factor"), V2 = c(-2.427, 0.004276057, -2.427, 
0.0018325958), V3 = c(-32.962, 0.0015271631, -32.962, 0.0033597588
), V4 = c(-61.097, -0.005192355, -60.783, -0.0021380284)), .Names = c("V1", 
"V2", "V3", "V4"), row.names = c(NA, 4L), class = "data.frame")

you can do

cbind(dd[seq(1,nrow(dd), by=2),], dd[seq(2,nrow(dd), by=2),])

#      V1     V2      V3      V4    V1          V2          V3           V4
# 1 type1 -2.427 -32.962 -61.097 type2 0.004276057 0.001527163 -0.005192355
# 3 type1 -2.427 -32.962 -60.783 type2 0.001832596 0.003359759 -0.002138028

to include the "type" column or you can do

cbind(dd[seq(1,nrow(dd), by=2),-1], dd[seq(2,nrow(dd), by=2),-1])

#       V2      V3      V4          V2          V3           V4
# 1 -2.427 -32.962 -61.097 0.004276057 0.001527163 -0.005192355
# 3 -2.427 -32.962 -60.783 0.001832596 0.003359759 -0.002138028

to leave it off

Upvotes: 3

Related Questions