How to create a data frame from a matrix without changing the number of rows and columns?

Viewed 93

I've created a table which combines figures (correlations) with significance (stars). I want to convert my data to a dataframe for further processing. I tried tibble and as.data.frame, but both turn my matrix into a 1xn frame. I'm obviously doing something wrong. But what?

R <- matrix(data=-3:2/10, ncol=3, nrow=2, byrow=TRUE)
mystars <- matrix(data=c("*  ", "*  ", "*  ", "***", "   ", "** "), ncol=3, nrow=2, byrow=TRUE)
R1 <- tibble(paste(R, mystars))
R2 <- as.data.frame(paste(R, mystars), stringsAsFactors = FALSE, ncol=3, nrow=2, byrow=TRUE)

This gives a 6x1 tibble and a 6x1 data frame, instead of the original 2x3 matrix.

2 Answers

You can use [] to preserve the dimensions of the original matrix.

R[] <- trimws(paste(R, mystars))

#       [,1]     [,2]     [,3]    
#[1,] "-0.3 *" "-0.2 *" "-0.1 *"
#[2,] "0 ***"  "0.1"    "0.2 **"

When you paste numbers and stars together, we get "character" data. However, the numbers won't be converted nicely (decimal zeros are deleted, negative numbers are wider than non-negative), unless we do that by hand.

r0 <- R < 0  ## store numbers less than zero
R <- formatC(R, format="f", digits=1)  ## format numbers to character
R[!r0] <- sprintf(" %s", R[!r0])  ## insert leading space for non-negative

Then we can use mapply with paste0 and convert first to an array, because of the nice dim= argument, and finally as.data.frame.

as.data.frame(array(mapply(paste0, R, mystars), dim=dim(R)))
#        V1      V2
# 1 -0.3*   -0.2*  
# 2 -0.1*    0.0***
# 3  0.1     0.2** 

Data:

R <- structure(c(-0.3, -0.1, 0.1, -0.2, 0, 0.2), .Dim = 3:2)
mystars <- structure(c("*  ", "*  ", "   ", "*  ", "***", "** "), .Dim = 3:2)
Related