Is it possible to NOT display NAs in a data frame?
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!!
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