Only with factors we can handle NAs by setting them as factor level. This is handy because many functions leave out NA values. Let's generate some toy data:
df <- data.frame(x= rnorm(10), g= c(sample(1:2, 9, replace= TRUE), NA))
If we want means of x grouped by g we can use
aggregate(x ~ g, df, mean)
g x
1 1 1.0415156
2 2 -0.3071171
As you can see we do not get the mean of x for the case where g is an NA. Same problem is true if we use by instead (see by(df$x, list(df$g), mean)). There are many other similiar examples where functions (by default or in general) do not consider NAs.
But we can add NA as a factor level. See here:
aggregate(x ~ addNA(g), df, mean)
addNA(g) x
1 1 -0.2907772
2 2 -0.2647040
3 <NA> 1.1647002
Yeah, we see the mean of x where g has NAs. One could argue that same output is possible with paste0 which is true (try aggregate(x ~ paste0(g), df, mean)). But only with addNA we can backtransform the NAs to actual missings. So let's firstly transform g with addNA and then backtransform it:
df$g_addNA <- addNA(df$g)
df$g_back <- factor(as.character(df$g_addNA))
[1] 2 2 1 1 1 2 2 1 1 <NA>
Levels: 1 2
Now the NAs in g_back are actual missings. See any(is.na(df$g_back)) which returns a TRUE.
This even works in strange situations where "NA" was a value in the original vector! For example, the vector vec <- c("a", "NA", NA) can be transformed using vec_addNA <- addNA(vec) and we can actually backtransform this with
as.character(vec_addNA)
[1] "a" "NA" NA
On the other hand, to my knowledge we can not backtransform vec_paste0 <- paste0(vec) because in vec_paste0 the "NA" and the NA are the same! See
vec_paste0
[1] "a" "NA" "NA"
I started the answer with "Only with factors we can handle NAs by setting them as factor level.". In fact I would be careful using addNA but regardless of the risk associated with addNA the fact stands that there is no similiar option for characters.