我想再问你一个问题.它主要是关于[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?有可能吗?
非常感谢,周末愉快,
拉斯洛
您可以简化重复呼叫:
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().使用你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
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)
| 归档时间: |
|
| 查看次数: |
567 次 |
| 最近记录: |