11

EDIT: The accepted answer has helped the scales fall from my eyes; this change is an improvement and not annoying after all.

In the help file for table, it is now written:

Non-factor arguments a are coerced via factor(a, exclude=exclude). Since R 3.4.0, care is taken not to count the excluded values (where they were included in the NA count, previously).

This is annoying. Before, you could call table(x, exclude = NULL) and get explicit confirmation of the number of NA values. Now, if there are none, you aren't told. Observe:

vec_with_no_nas <- c("A", "B", "B", "C")
vec_with_nas <- c("A", "B", NA, "C")

table(vec_with_no_nas)
table(vec_with_no_nas, exclude = NULL)

table(vec_with_nas)
table(vec_with_nas, exclude = NULL)

This gives output:

> table(vec_with_no_nas)
vec_with_no_nas
A B C 
1 2 1 
> table(vec_with_no_nas, exclude = NULL)
vec_with_no_nas
A B C 
1 2 1 

See? no explicit confirmation of zero NAs.

What I really want is something like the old behavior, which was:

> table(vec_with_no_nas, exclude = NULL)
vec_with_no_nas
A B C <NA>
1 2 1 0

FWIW, if the vector does have NA values, table(x, exclude = NULL) will tell you:

> table(vec_with_nas)
vec_with_nas
A B C 
1 1 1 

> table(vec_with_nas, exclude = NULL)
vec_with_nas
   A    B    C <NA> 
   1    1    1    1 

I work in base and in the tidyverse. Is there a drop-in table replacement that will do explicit confirmation of no NAs?

lmo
  • 37,904
  • 9
  • 56
  • 69
Alex Coppock
  • 2,122
  • 3
  • 15
  • 31
  • Maybe you could use the `useNA` argument? `table(vec_with_no_nas, useNA="always")`. I currently don't have access to 3.4.0 to test directly. – lmo Jun 28 '17 at 12:59
  • That does it! if you put table(vec_with_nas, useNA = "always") table(vec_with_no_nas, useNA = "always") in an answer, I'll accept it! – Alex Coppock Jun 28 '17 at 13:06

3 Answers3

20

You can try setting the useNA argument to "always". In R 3.2.5,

table(vec_with_no_nas, useNA="always")

adds an NA column, even though no NAs are present.

vec_with_no_nas
   A    B    C <NA> 
   1    2    1    0 

The online help file for 3.4.0 (and 3.2.5) says

useNA controls if the table includes counts of NA values.

So this argument seems to do directly address what you want to do. The exclude argument allows the user to directly drop levels of a factor variable from the table output.

table(vec_with_no_nas, exclude="A")
vec_with_no_nas
B C 
2 1 

Which can be cleaner than dropping unwanted levels from a constructed table object.

note:
The online 3.4.0 help file mentions a pathological case in the simultaneous use of both exclude and useNA arguments and also provides an example that might be worth further exploration.

lmo
  • 37,904
  • 9
  • 56
  • 69
  • I noticed that in R 4.1.3 `useNA` defaults to `"no"`, which I think is suboptimal because NAs will get dropped implicitly. `useNA="ifany"` is my favorite and should be default imho. – Mario Reutter Apr 07 '22 at 10:04
  • P.S.: Using `summary()` instead of `table()` automatically invokes `table(useNA="ifany")` for factors as input – Mario Reutter Apr 07 '22 at 10:17
0

data.table can be used to quickly create summary tables and includes NAs by default.

# Create Dataset
library(data.table)
df=data.table(V1=c('A','B','B',NA),V2=1:4)
df
#      V1 V2
# 1:    A  1
# 2:    B  2
# 3:    B  3
# 4: <NA>  4

# Count Table
df[,.N,by=V1]
#      V1 N
# 1:    A 1
# 2:    B 2
# 3: <NA> 1

# Proportion Table
df[,.N/nrow(df),by=V1]
#      V1   V1
# 1:    A 0.25
# 2:    B 0.50
# 3: <NA> 0.25
kakarot
  • 376
  • 4
  • 13
0

Sometimes you can use sum(is.na(dataset$columnname))

table(is.na(dataset$variablecolumn))
table(is.na(dataset$columnname))
Adriaan
  • 17,741
  • 7
  • 42
  • 75
John
  • 1
  • 1
  • this is not an answer to the question. You are filtering out `NA` values while th question asks to include the alongside other values. – Dandelion Nov 15 '22 at 08:16