dan
dan

Reputation: 6314

Reformatting an R's data.frame

I have a data.frame of this format:

set.seed(1)
pl.mat <-matrix(rnorm(500*1000),nrow=500,ncol=1000)
colnames(pl.mat) <- gsub("\\s+","",apply(expand.grid(paste("pl",1:10,sep=""),1:100),1,function(x) paste(unlist(x),collapse=".")),perl=T)
df <- cbind(data.frame(id=1:500,group.id=rep(1:25,20)),pl.mat)

> df[1:5,1:5]
  id group.id      pl1.1       pl2.1       pl3.1
1  1        1 -0.6264538  0.07730312  1.13496509
2  2        2  0.1836433 -0.29686864  1.11193185
3  3        3 -0.8356286 -1.18324224 -0.87077763
4  4        4  1.5952808  0.01129269  0.21073159
5  5        5  0.3295078  0.99160104  0.06939565

df$id are grouped by df$group.id. Then each column has an experimental plate id (pl1-pl10), and the integer following the period separator is a well id (1-100). Hence each plate has 100 columns.

I want to build a new data.frame which these columns: df$id, df$group.id, well id, and the all plates.

Meaning this format:

id group.id      well.id      pl1       pl2       pl3
1  1             1     -0.6264538 0.07730312  1.13496509
1  1             2            ...       ...       ...
.
.
.
1  2             1            ...       ...       ...
.
.
.
500 25 .        100           ...       ...       ...

Any good concise code for that?

Upvotes: 0

Views: 29

Answers (2)

SommerEngineering
SommerEngineering

Reputation: 1700

Dan, you could create a new data.frame with the desired columns. Let's say you want column df$id and df$group.id:

newDF <- as.data.frame(cbind(df$id, df$group.id))

Now, if you had such a huge amount of columns where you cannot write-out any, you could use the index as well:

newDF <- as.data.frame(cbind(df[,2], df[,5]))

Therefore, also ranges work:

newDF <- as.data.frame(cbind(df[,2:210], df[,507:1020]))

Does this work for you? Another solution would be to use a loop and construct the indices or column names dynamically. Here a draft:

for(i in 1:10) {
  print(eval(parse(text=paste("df$id", i, sep = ""))))
}

Here, the column names df$id1 up to df$id10 gets build dynamically.

Best regards, Thorsten

Upvotes: 1

Adam Quek
Adam Quek

Reputation: 7153

df %>% 
  gather(var, val, -id, -group.id) %>%
  separate(var, c("pl.id", "well.id")) %>% 
  spread(pl.id, val)

Upvotes: 1

Related Questions