Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paste together two data frames element by element in R

Tags:

r

I need to paste, element by element, the contents of two data frames for input to another program. I have a data frame of means and a data frame of standard errors of the mean.

I tried using the R paste() function, but it doesn't seem to be able to cope with data frames. When using a vector, it seems to concatenate all the elements of the first vector into a string and all the elements of the second into a separate string. Instead, I need each reciprocal element in the two data frames to be concatenated together.

Any suggestions for how to approach this? I've included dummy input data (datMean and datSE) and my desired output (datNew). My real data frames are about 10 rows by 150 columns in size.

# means and SEM
datMean <- data.frame(a=rnorm(10, 3), b=rnorm(10, 3), d=rnorm(10, 3))
datSE <- data.frame(a=rnorm(10, 3)/100, b=rnorm(10, 3)/100, d=rnorm(10, 3)/100)

# what the output should look like
# i've chosen some arbitrary values here, and show only the first row. 
datNew <- data.frame(a="2.889-2.926", b="1.342-1.389", d="2.569-2.576")

The idea is for each element in datNew to be a range consisting of 'mean - se' and 'mean + se', separated by a dash '-' . The paste() function can do this for one element, how to do this over the whole dataframe?

paste(datMean[1,1] - datSE[1,1], datMean[1,1] + datSE[1,1], sep="-")

EDIT 1: Looking at some of the answers I realize I left out an important bit of information in the question. Each row of the original data frames is named, and I need to reconstitute the final data frame with these names. For example:

rownames(datMean) <- LETTERS[1:10]
rownames(datSE) <- LETTERS[1:10]

I need datNew to eventually have these 10 rownames again. This could be problematic with some of the solutions using melt().

like image 664
Steve Avatar asked Jun 20 '11 07:06

Steve


1 Answers

If you convert to matrices first, you can do it with no applies or loops at all.

MdatMean <- as.matrix(datMean)
MdatSE <- as.matrix(datSE)
matrix( paste(MdatMean - MdatSE, MdatMean + MdatSE, sep="-"), 
        nrow=nrow(MdatMean), dimnames=dimnames(MdatMean) )

You also might consider formatC for better formatting.

lo <- formatC(MdatMean - MdatSE, format="f", digits=3)
hi <- formatC(MdatMean + MdatSE, format="f", digits=3)
matrix( paste(lo, hi, sep="-"), 
        nrow=nrow(MdatMean), dimnames=dimnames(MdatMean) )

If you want a data.frame in the end just wrap the last line in as.data.frame.

like image 144
Aaron left Stack Overflow Avatar answered Sep 23 '22 18:09

Aaron left Stack Overflow