计算R中的频率

时间:2014-04-02 05:49:55

标签: r frequency

我的数据集如下所示:

genera
             Genus Location Number
    1                             NA
    2    Terriglobus       CC      1
    3    Terriglobus        N      5
    4 Acidobacterium       CC      2
    5 Acidobacterium        N     12
    6   Edaphobacter       CC      0

我想做两件事1)删除任何列中任何NA的行,2)计算位置,CC和N中每个属的频率。

我一直在尝试使用

AB<-genera[genera[, "Location"] == "CC", ] #to keep all separate the rows by location 
CD<-genera[genera[, "Location"] == "N", ]

我想使用表格或prop.table并计算每个频率,但我遇到了困难因为我得到NA NA NA NA NA NA NA

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

prop.table需要一个表对象开头:

 prop.table( table(genera$CC) )

如果&#34; Number&#34;是一个计数,那么你可能希望tapply总和为Number。也许是这些方面的事情:

prop.table( with(genera, tapply(Number, CC, sum) ) )

xtabs也会做总结:

 prop.table( xtabs( Number ~ CC, data=genera) )

答案 1 :(得分:3)

我必须添加两个NULL值来制作表格。

> dat <- read.table(header = TRUE, text = 'Genus Location Number
  1           NULL     NULL     NA
  2    Terriglobus       CC      1
  3    Terriglobus        N      5
  4 Acidobacterium       CC      2
  5 Acidobacterium        N     12
  6   Edaphobacter       CC      0', row.names = 1)

关于您的第一个问题,您可以使用whichis.na

删除包含NA编号的行
> newDat <- dat[-which(is.na(dat$Number)), ]
> newDat
           Genus Location Number
2    Terriglobus       CC      1
3    Terriglobus        N      5
4 Acidobacterium       CC      2
5 Acidobacterium        N     12
6   Edaphobacter       CC      0

对于你的第二个问题,我认为你的频率和百分比(或概率)可能会混淆。

可以找到频率
> sapply(split(newDat, as.character(newDat$Genus)), function(x){
    sum(x$Number)
    })
Acidobacterium   Edaphobacter    Terriglobus 
            14              0              6 

百分比略有不同,

> pct <- with(newDat, Number/sum(Number))
> names(pct) <- newDat$Location

这将按顺序告诉您重量占每个地点相对于总数的百分比。

> pct
  CC    N   CC    N   CC 
0.05 0.25 0.10 0.60 0.00 

<强> ADDED

第二个想法,你可能只需要

> split(newDat[,c("Location", "Number")], newDat$Genus)
$Acidobacterium
  Location Number
4       CC      2
5        N     12

$Edaphobacter
  Location Number
6       CC      0

$Terriglobus
  Location Number
2       CC      1
3        N      5

答案 2 :(得分:2)

以下是我如何使用@ RichardScriven&#39; s dat

with(na.omit(dat), aggregate(Number, list(Genus=Genus, Location=Location), sum))

#            Genus Location  x
# 1 Acidobacterium       CC  2
# 2   Edaphobacter       CC  0
# 3    Terriglobus       CC  1
# 4 Acidobacterium        N 12
# 5    Terriglobus        N  5

修改

鉴于您对其他解决方案的评论已经澄清,我现在建议以下内容,为每个GenusLocation计算NumberNumber总和的比例{1}}在该位置。再次,从@ RichardScriven&#39; dat开始。

do.call(rbind, lapply(unique(dat$Location), function(x) {
  d <- subset(dat, Location==x)
  cbind(Location=x, aggregate(d$Number, list(Genus=d$Genus), 
                              function(x) sum(x)/sum(d$Number)))
}))

#   Location          Genus         x
# 1       CC Acidobacterium 0.6666667
# 2       CC   Edaphobacter 0.0000000
# 3       CC    Terriglobus 0.3333333
# 4        N Acidobacterium 0.7058824
# 5        N    Terriglobus 0.2941176

但是,如果每个GenusLocation只出现一次,则可以简化为:

lapply(split(dat, list(dat$Location), drop=TRUE), function(x) 
  transform(x, propn=x$Number/sum(x$Number)))

# $CC
#            Genus Location Number     propn
# 2    Terriglobus       CC      1 0.3333333
# 4 Acidobacterium       CC      2 0.6666667
# 6   Edaphobacter       CC      0 0.0000000
# 
# $N
#            Genus Location Number     propn
# 3    Terriglobus        N      5 0.2941176
# 5 Acidobacterium        N     12 0.7058824

然后可以将其与do.call(rbind, x)合并为一个数据框,其中x是上面创建的列表。

最后,您可以使用dplyr,如下所示:

library(dplyr)
dat %.%
  group_by(Location) %.%
  mutate(total = sum(Number), Propn = Number/total) %.%
  select(-total)

#            Genus Location Number     Propn
# 1    Terriglobus       CC      1 0.3333333
# 2    Terriglobus        N      5 0.2941176
# 3 Acidobacterium       CC      2 0.6666667
# 4 Acidobacterium        N     12 0.7058824
# 5   Edaphobacter       CC      0 0.0000000