"说服"制表函数来计算[R]中数据框中的NA

Las*_*zlo 1 r dataframe

我想再问你一个问题.它主要是关于[R]中的数据帧,NA和制表功能.

我有这个数据框.我已经在之前的一个问题中使用了这个.它故意看起来很简单,我真正的"df"数据框实际上要大得多,我不愿意惹恼任何拥有庞大数据库的人...所以,我的数据库:

id <-c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3)
a <-c(3,1,3,3,1,3,3,3,3,1,3,2,1,2,1,3,3,2,1,1,1,3,1,3,3,3,2,1,1,3)
b <-c(3,2,1,1,1,1,1,1,1,1,1,2,1,3,2,1,1,1,2,1,3,1,2,2,1,3,3,2,3,2)
c <-c(1,3,2,3,2,1,2,3,3,2,2,3,1,2,3,3,3,1,1,2,3,3,1,2,2,3,2,2,3,2)
d <-c(3,3,3,1,3,2,2,1,2,3,2,2,2,1,3,1,2,2,3,2,3,2,3,2,1,1,1,1,1,2)
e <-c(2,3,1,2,1,2,3,3,1,1,2,1,1,3,3,2,1,1,3,3,2,2,3,3,3,2,3,2,1,4)
df <-data.frame(id,a,b,c,d,e)
df
Run Code Online (Sandbox Code Playgroud)

我已经设法计算了在'b'到'e'列中出现的数字的分布,但同时考虑到这些分布应该由'id'列中的id号"分组"的事实.它工作正常,检查 - >

matrix(matrix(unlist(lapply(df[,(-(1))], 
       function(x) tapply(x,df$id,tabulate,
                          nbins=nlevels(factor(df[,2])))) [[1]])), 
              ncol=3,nrow=3,byrow=TRUE)

matrix(matrix(unlist(lapply(df[,(-(1))],function(x) tapply(x,df$id,tabulate,nbins=nlevels(factor(df[,3])))) [[2]])),ncol=3,nrow=3,byrow=TRUE)

matrix(matrix(unlist(lapply(df[,(-(1))],function(x) tapply(x,df$id,tabulate,nbins=nlevels(factor(df[,4])))) [[3]])),ncol=3,nrow=3,byrow=TRUE)

matrix(matrix(unlist(lapply(df[,(-(1))],function(x) tapply(x,df$id,tabulate,nbins=nlevels(factor(df[,5])))) [[4]])),ncol=3,nrow=3,byrow=TRUE)

matrix(matrix(unlist(lapply(df[,(-(1))],function(x) tapply(x,df$id,tabulate,nbins=nlevels(factor(df[,6])))) [[5]])),ncol=4,nrow=3,byrow=TRUE)
Run Code Online (Sandbox Code Playgroud)

现在我的问题是:如果我的数据框在这里和那里包含NA值,如果我希望我的内置制表函数也能收集这些NA怎么办?那么如果我想要计算这些NA的出现次数呢?

这是我修改过的数据框与NA:

id <-c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3)
a <-c(NA,1,3,3,1,3,3,3,3,1,3,2,1,2,1,3,3,2,1,1,1,3,1,3,3,3,2,1,1,3)
b <-c(3,2,1,1,1,1,1,1,1,1,1,2,1,3,2,1,1,1,2,1,3,1,2,2,1,3,3,2,3,2)
c <-c(1,3,2,3,2,1,2,3,3,2,2,3,NA,2,3,3,3,1,1,2,3,3,1,2,2,3,2,2,3,2)
d <-c(3,3,3,1,3,2,2,1,2,3,2,2,2,1,3,1,2,2,3,2,3,2,3,2,1,1,1,1,1,2)
e <-c(2,3,1,2,1,2,3,3,1,1,2,1,1,3,3,2,1,1,3,3,2,2,3,3,3,2,3,NA,1,4)
df <-data.frame(id,a,b,c,d,e)
df
Run Code Online (Sandbox Code Playgroud)

起初我尝试过这样的事情:

unlist(lapply(df[,(-(1))],function(x) tapply(x,df$id,tabulate,nbins=nlevels(factor(df[,2],exclude=NULL)))) [[1]])
Run Code Online (Sandbox Code Playgroud)

你看,我唯一做的就是我试图应用这个exclude=NULL东西.

至少我的代码意识到我在列中有4个不同的级别,a (1,2,3,NA)而不仅仅是3个(1,2,3).在这里查看:

nlevels(factor(df[,2], exclude=NULL))
Run Code Online (Sandbox Code Playgroud)

但是你在结果中看到它无法以某种方式计算NA.它说

3  0  6  0  4  3  3  0  4  1  5  0 
Run Code Online (Sandbox Code Playgroud)

而不是正确的:

3  0  6  1  4  3  3  0  4  1  5  0
Run Code Online (Sandbox Code Playgroud)

或者在以下情况下:

unlist(lapply(df[,(-(1))],function(x) tapply(x,df$id,tabulate,nbins=nlevels(factor(df[,4],exclude=NULL)))) [[3]])
Run Code Online (Sandbox Code Playgroud)

它说

2  4  4  0  2  3  4  0  1  5  4  0
Run Code Online (Sandbox Code Playgroud)

而不是正确的

2  4  4  0  2  3  4  1  1  5  4  0
Run Code Online (Sandbox Code Playgroud)

等等

有人有任何想法如何"说服"函数列表来计算NA?有可能吗?

非常感谢,周末愉快,

拉斯洛

Rei*_*son 6

您可以简化重复呼叫:

tabs <-lapply(df[,2:6], function(x, id){ t(table(x, id)) }, df$id)
Run Code Online (Sandbox Code Playgroud)

它与您重复的矩阵调用几乎相同,例如对于您的第一个(非NA)调用:

> tabs[[1]]
   x
id  1 2 3
  1 3 0 7
  2 4 3 3
  3 4 1 5
Run Code Online (Sandbox Code Playgroud)

那么我们现在可以修改这个来处理NA吗?是的,使用函数的useNA参数table().使用你dfNA,我们有:

tabs <-lapply(df[,2:6], 
              function(x, id){ t(table(x, id, useNA = "ifany")) }, df$id)

> tabs[[1]]
   x
id  1 2 3 <NA>
  1 3 0 6    1
  2 4 3 3    0
  3 4 1 5    0
Run Code Online (Sandbox Code Playgroud)

因为我们要求NA在表中只能如果NA存在,而不是在所有的表tabs具有相同的列数.如果这很重要,我们可以更改useNA = "ifany"为be,useNA = "always"并且所有结果表将具有相同的列数,但是它会添加另一个id行:

> tabs[[1]]
      x
id     1 2 3 <NA>
  1    3 0 6    1
  2    4 3 3    0
  3    4 1 5    0
  <NA> 0 0 0    0
Run Code Online (Sandbox Code Playgroud)

最后一个添加得到我们想要的 - 我们用来addNA()NA每组id数字添加一个级别,即使没有NA记录:

tabs <-lapply(df[,2:6], 
              function(x, id){ t(table(addNA(x), id, useNA = "ifany")) }, df$id)
Run Code Online (Sandbox Code Playgroud)

这使:

> tabs
$a

id  1 2 3 <NA>
  1 3 0 6    1
  2 4 3 3    0
  3 4 1 5    0

$b

id  1 2 3 <NA>
  1 8 1 1    0
  2 6 3 1    0
  3 2 4 4    0

$c

id  1 2 3 <NA>
  1 2 4 4    0
  2 2 3 4    1
  3 1 5 4    0

$d

id  1 2 3 <NA>
  1 2 3 5    0
  2 2 6 2    0
  3 5 3 2    0

$e

id  1 2 3 4 <NA>
  1 4 3 3 0    0
  2 4 2 4 0    0
  3 1 3 4 1    1
Run Code Online (Sandbox Code Playgroud)