Question

I am trying to create a data.frame where some cells have missing values. Instead of showing NAs, I wonder if there is any way to hide the NAs? What I want essentially is like an ANOVA table as shown below.

 x = rnorm(40)    
 y = rep(1:2, each=20)    
 z = rep(c(1,2,1,2), each=10)  
 model1 = lm(x~y * z)  
 model2 = lm(x~y + z)  
 anova(model1, model2)  

 #Analysis of Variance Table
 #Model 1: x ~ y * z
 #Model 2: x ~ y + z
 #Res.Df    RSS Df Sum of Sq      F Pr(>F)
 #1     36 38.931                           
 #2     37 39.248 -1  -0.31705 0.2932 0.5915

The output is above. If you try to access those blank cells, you will get NAs

 anova(model1, model2)[1,4]
 #[1] NA

Thanks in advance!!

Was it helpful?

Solution

print.anova works by using the na.print option of print.default, like this:

> x <- matrix(c(101:111/100, NA), nrow=3)
> print(x, na.print="")
     [,1] [,2] [,3] [,4]
[1,] 1.01 1.04 1.07 1.10
[2,] 1.02 1.05 1.08 1.11
[3,] 1.03 1.06 1.09     

However, this only works for matrices, not for data frames.

For data frames, the suggestion of replacing the NA's with "" is good, but loses the usual printing of digits; you can do so by using format.data.frame before replacement. Read the print.data.frame function for more details. Doing it this way, you can also replace with NA and then use the na.print option, as above.

> y <- as.data.frame(x)
> m <- as.matrix(format.data.frame(y, digits = NULL, na.encode = FALSE))
> m[is.na(y)] <- NA
> print(m, na.print="", quote=FALSE)
  V1   V2   V3   V4  
1 1.01 1.04 1.07 1.10
2 1.02 1.05 1.08 1.11
3 1.03 1.06 1.09   

See how the digits in the fourth column line up? Compare to this.

> z <- y
> z[is.na(z)] <- ""
> print(z)
    V1   V2   V3   V4
1 1.01 1.04 1.07  1.1
2 1.02 1.05 1.08 1.11
3 1.03 1.06 1.09     

OTHER TIPS

The question is a bit confusing. But I think you have a table with NAs and you don't want the NAs to appear like in the anova table you gave? If this is correct you can index to find the NAs and replace with "":

(w <- data.frame(anova(model1, model2))) #your example as a data frame with NAs
w[is.na(w)] <- ""                        #index to find NAs and replace with ""
w

Aaron's answer (which is a good one) relies on print.default -- I found this less than ideal because I needed to use row.names = FALSE, which is supported only in print.data.table. (And quote=FALSE is the default on print.data.table, so one less thing to worry about there.)

You don't have to convert your data.table to a matrix, you can convert it to a list of character and back to a data.frame, like this:

prettyPrintDf <- function(df, ...) # My function
  print(format.data.frame(data.frame(lapply(df, as.character)), na.encode = FALSE), 
        na.print="", ...)

So given a data.frame like

some_df <- data.frame(a = c(1,2,NA), b = c(4,NA,6), c = letters[1:3])

You can do:

> prettyPrintDf(some_df, row.names=FALSE)
 a b c
 1 4 a
 2   b
   6 c
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top