首页 > 解决方案 > 计算数据框中组行的频率

问题描述

我正在寻找一种将我的数据框转换为如下所示格式的方法out。基本上,对于每个物种,我将展示Freq它在每个物种中出现的频率( )group,频率计算为计数 <0 的样本与计数 >0 的样本的比率。如果我有 10 个样本且 3 个样本的计数 > 0,则比率为 0.3。另外,我想要一列具有计数> 0的绝对样本数。

我玩过dplyr::mutate我认为应该工作的地方。

> df
         sample1 sample2 sample3 sample4
Species1       2      12      52     221
Species2       0      13       0       0
Species3       5       0       0      25
Species4       0       0       0       0
Group        Gr1     Gr1     Gr2     Gr2


> dput(df)
structure(list(sample1 = c("2", "0", "5", "0", "Gr1"), sample2 = c("12", 
"13", "0", "0", "Gr1"), sample3 = c("52", "0", "0", "0", "Gr2"
), sample4 = c("221", "0", "25", "0", "Gr2")), class = "data.frame", row.names = c("Species1", 
"Species2", "Species3", "Species4", "Group"))





 out

Species Group Freq Absolute
Species1 Gr1 1 2
Species1 Gr2 1 2
Species2 Gr1 0.5 1
Species2 Gr2 0 0
Species3 Gr1 0.5 1
Species3 Gr2 0.5 1
Species4 Gr1 0 0
Species4 Gr2 0 0
 

标签: rdplyrplyr

解决方案


这里的问题是,虽然df从技术上讲是一个数据框,但它的结构并不好。数据框每个变量应该有一列,每个观察值应该有一行。如果先转置,您的数据会更有意义:

library(tibble)
library(dplyr)

df <- rownames_to_column(as.data.frame(t(df)), "sample")

df[2:5] <- lapply(df[2:5], as.numeric)

df

#>    sample Species1 Species2 Species3 Species4 Group
#> 1 sample1        2        0        5        0   Gr1
#> 2 sample2       12       13        0        0   Gr1
#> 3 sample3       52        0        0        0   Gr2
#> 4 sample4      221        0       25        0   Gr2

现在我们可以旋转以创建Species自己的列,并且可以直接进行所需的计算:

tidyr::pivot_longer(df, 2:5) %>%
  group_by(name, Group) %>%
  summarise(absolute = sum(value > 0),
            Freq = absolute / length(name))

#> # A tibble: 8 x 4
#> # Groups:   name [4]
#>   name     Group absolute  Freq
#>   <chr>    <chr>    <int> <dbl>
#> 1 Species1 Gr1          2   1  
#> 2 Species1 Gr2          2   1  
#> 3 Species2 Gr1          1   0.5
#> 4 Species2 Gr2          0   0  
#> 5 Species3 Gr1          1   0.5
#> 6 Species3 Gr2          1   0.5
#> 7 Species4 Gr1          0   0  
#> 8 Species4 Gr2          0   0  

推荐阅读