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

时间:2011-03-19 14:30:50

标签: 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

我已经设法计算了“b”到“e”列中出现的数字的分布,但同时考虑到这些分布应该被“id”列中的id号“分组”的事实。它工作正常,检查它 - &gt;

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)

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

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

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

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

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

你知道,我唯一做过的就是我试图应用这个exclude=NULL的东西。

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

nlevels(factor(df[,2], exclude=NULL))

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

3  0  6  0  4  3  3  0  4  1  5  0 

而不是正确的:

3  0  6  1  4  3  3  0  4  1  5  0

或者在以下情况下:

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

它说

2  4  4  0  2  3  4  0  1  5  4  0

而不是正确的

2  4  4  0  2  3  4  1  1  5  4  0

是否有人有任何想法如何“说服”函数列表来计算NA?它有可能吗?

非常感谢,周末愉快,

的Laszlo

2 个答案:

答案 0 :(得分:6)

您可以简化重复呼叫:

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

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

> tabs[[1]]
   x
id  1 2 3
  1 3 0 7
  2 4 3 3
  3 4 1 5

我们现在可以修改它来处理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

因为如果NA存在,我们只在表 中要求NA,并非tabs中的所有表都具有相同的列数。如果这很重要,我们可以将useNA = "ifany"更改为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

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

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

给出了:

> 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

答案 1 :(得分:0)

你不能只使用is.na吗?如果您想要计算NA或非零的条目数,您可以sum(is.na(my.var)|my.var>0)