In R, can I make the table () function return the number of NA values ​​in a named element?

I use R to summarize a large amount of data for a report. I want to be able to use lapply()to create a list of tables from a function table()from which I can extract the necessary statistics. There are many of them, so I wrote a function to do this. My problem is that it is difficult for me to return the number of missing values ​​( NA), although I have it in every table, because I can’t understand how to tell R that I want an element from the table()number of values NA. As far as I can tell, R "calls" this element NA... and I can't call it.

I try to avoid writing a complicated statement where I say something like which(is.na(names(element[1]))) | names(element[1])=="var_I_want"that because I feel that it is just very verbose. I was hoping there was some way to tell R to label the variable NAin each table with the name of the symbol or tell her to select the one that was marked NA, but I still failed.

Minimal example:

example <- data.frame(ID=c(10,20,30,40,50),
                      V1=c("A","B","A",NA,"C"),
                      V2=c("Dog","Cat",NA,"Cat","Bunny"),
                      V3=c("Yes","No","No","Yes","No"),
                      V4=c("No",NA,"No","No","Yes"),
                      V5=c("No","Yes","Yes",NA,"No"))

varlist <- c("V1","V2","V3","V4","V5")

list_o_tables <- lapply(X=example[varlist],FUN=table,useNA="always")

list(V1=list_o_tables[["V1"]]["A"],
     V2=list_o_tables[["V2"]]["Cat"],
     V3=list_o_tables[["V3"]]["Yes"],
     V4=list_o_tables[["V4"]]["Yes"],
     V5=list_o_tables[["V5"]]["Yes"])

What I get:

$V1
A 
2 

$V2
Cat 
  2 

$V3
Yes 
  2 

$V4
Yes 
  1 

$V5
Yes 
  2

What I need:

$V1
A     <NA>
2       1

$V2
Cat   <NA>
  2     1

$V3
Yes   <NA> 
  2     0

$V4
Yes   <NA> 
  1     1

$V5
Yes   <NA> 
  2     1
+4
source share
4 answers

This is ugly (IMHO), but it works:

my_table <- function(x){
    setNames(table(x,useNA = "always"),c(sort(unique(x[!is.na(x)])),'NA'))
}

So, you would use instead lapply, and then you would have access to the column NA.

More carefully, this is due to the behavior factor:

levels(factor(c(1,NA,2),exclude = NULL))
[1] "1" "2" NA 

, NA "NA" , , R . , r-devel, .

, , NA, ? , "" "NA". (IMHO), table .

+3

tab[match(NA, names(tab))], , , tab[NA], tab[NA_character_], tab["NA_character_"], tab["<NA>"] .. .. .....

f <- function(nms, obj) {
    obj[sapply(c(nms, NA), function(X) match(X, names(obj)))]
}

f("Cat", list_o_tables[["V2"]])
#  Cat <NA> 
#    2    1 

mapply(f, list("A", "Cat", "Yes", "Yes", "Yes"), list_o_tables, SIMPLIFY=FALSE)
# [[1]]
# 
#    A <NA> 
#    2    1 
# 
# [[2]]
# 
#  Cat <NA> 
#    2    1 
# 
# [[3]]
# 
#  Yes <NA> 
#    2    0 
# 
# [[4]]
# 
#  Yes <NA> 
#    1    1 
# 
# [[5]]
# 
#  Yes <NA> 
#    2    1 
+3

When you install useNA="always", it table()always adds NAas the last result, so one way to do this is to use it tailto your advantage. Suppose we have yours liston top (which I will name l1) ...

l1 <- list(V1=list_o_tables[["V1"]]["A"],
     V2=list_o_tables[["V2"]]["Cat"],
     V3=list_o_tables[["V3"]]["Yes"],
     V4=list_o_tables[["V4"]]["Yes"],
     V5=list_o_tables[["V5"]]["Yes"])

We can receive NAand then attach them like this.

l2 <- lapply( list_o_tables , tail , 1 )
mapply( c , l1, l2 , SIMPLIFY = FALSE )
#$V1
#   A <NA> 
#   2    1 

#$V2
# Cat <NA> 
#   2    1 

#$V3
# Yes <NA> 
#   2    0 

#$V4
# Yes <NA> 
#   1    1 

#$V5
# Yes <NA> 
#   2    1 
+2
source

Why not just fix the names after the fact?

tables <- lapply(example[-1], table, useNA = "ifany")

fix_names <- function(x) {
  names(x)[is.na(names(x))] <- "<NA>"
  x
}
lapply(tables, fix_names)
+2
source

All Articles