我想再问你一个问题。它主要是关于[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
答案 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()
参数。将您的df
与NA
一起使用,我们有:
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)
。