【问题标题】:Using R - frequency counts with variable binwidths and factors使用具有可变 binwidth 和因子的 R 频率计数
【发布时间】:2015-08-18 13:14:11
【问题描述】:

我有一个相当大的数据集(超过 100 万行),其中有一个小样本:

structure(list(Feret = c(0.017, 0.016, 2.12, 0.016, 0.02, 0.023, 
0.017, 0.021, 0.02, 0.016, 0.027, 0.052, 0.061, 0.033, 0.041, 
0.017, 6.561, 7.123, 0.027, 0.018, 0.024, 4.099, 0.022, 0.025, 
0.037, 0.037, 0.018, 0.039, 0.027, 0.053, 0.016, 0.107, 0.52, 
0.041, 0.038, 0.039, 0.03, 0.071, 0.022, 0.118, 0.032, 0.018, 
0.027, 0.035, 8.113, 0.078, 4.089, 0.035, 0.057, 6.905, 2.5, 
0.282, 0.045, 0.039, 0.071, 0.037, 0.029, 0.027, 0.016, 0.02, 
0.026, 0.025, 0.026, 0.016, 0.016, 0.021), sample.type = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L), .Label = c("flower", "leaf"), class = "factor"), leaf.side = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = c("lower", "upper"), class = "factor"), canopy = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L), .Label = c("bottom", "top"), class = "factor"), treatment = structure(c(1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L), .Label = c("blue", "green", "grey", "white", "yel-green"
), class = "factor")), .Names = c("Feret", "sample.type", "leaf.side", 
"canopy", "treatment"), row.names = c(500000L, 500001L, 500002L, 
500003L, 500004L, 500005L, 500006L, 500007L, 500008L, 500009L, 
500010L, 800000L, 800001L, 800002L, 800003L, 800004L, 800005L, 
800006L, 800007L, 800008L, 800009L, 800010L, 1000L, 1001L, 1002L, 
1003L, 1004L, 1005L, 1006L, 1007L, 1008L, 1009L, 1010L, 10000L, 
10001L, 10002L, 10003L, 10004L, 10005L, 10006L, 10007L, 10008L, 
10009L, 10010L, 100000L, 100001L, 100002L, 100003L, 100004L, 
100005L, 100006L, 100007L, 100008L, 100009L, 100010L, 1160000L, 
1160001L, 1160002L, 1160003L, 1160004L, 1160005L, 1160006L, 1160007L, 
1160008L, 1160009L, 1160010L), class = "data.frame")

我一直在尝试使用以下 binswidths 创建“Feret”变量的频率计数:

bins <- c(0.01,0.03,0.1,0.3,1,3,10)

然后使用:

freq<-hist(df_temp$Feret, breaks=bins)
ranges<-paste(head(bins,-1),bins[-1],sep=" - ")
freq$counts
df5<-data.frame(ranges = ranges, frequency = freq$counts)
df5

但我真正需要做的是将 data.frame 按各种因素(“sample.type”、“leaf.side”、“canopy”、“treatment”)拆分,并提取每个子集的频率计数。 我可以通过手动创建每个子集来以冗长的方式做到这一点,但我想以更好的方式做到这一点。我尝试使用循环来创建子集,然后将 hist() 函数应用于每个子集,但这需要很长时间。有没有更好的方法使用 Dplyr 或 Apply? 我更愿意将结果放在一个表格中,然后我可以根据需要绘制它们。

【问题讨论】:

  • 可能类似于df %&gt;% mutate(Feret = cut(Feret, breaks = bins)) %&gt;% count_(., names(.))?
  • 类似table(cut(df$Feret, bins))

标签: r count dplyr


【解决方案1】:

下面的 sn-p 应该做你想做的事:

我已将您的示例加载到 df

library("dplyr")
df %>% group_by(sample.type, leaf.side, canopy, treatment) %>%
  dplyr::select(Feret) %>%
  do(data.frame(table(cut(.$Feret, breaks=bins, include.lowest=T))))

我将您推荐给dplyr documentation。简而言之,x %&gt;% ff(x)x -&gt; f(a)f(x,a)

请注意,dplyr::select 只是 select,但我已经多次遇到命名空间问题,所以现在我总是指定包。

table(cut(df$Feret, breaks=bins)) 只是一种更好的方式来执行您对 hist 所做的操作。使用cut,您可以创建一个因子变量(如果您的值可以达到下限,请记住添加 include.lowest=T),使用table,您可以计算每个级别的频率。

这给出了:

   sample.type leaf.side canopy treatment        Var1 Freq
1       flower     upper    top     green (0.01,0.03]    0
2       flower     upper    top     green  (0.03,0.1]    6
3       flower     upper    top     green   (0.1,0.3]    1
4       flower     upper    top     green     (0.3,1]    0
5       flower     upper    top     green       (1,3]    1
6       flower     upper    top     green      (3,10]    3
7       flower     upper    top     white (0.01,0.03]    4
8       flower     upper    top     white  (0.03,0.1]    4
9       flower     upper    top     white   (0.1,0.3]    0
10      flower     upper    top     white     (0.3,1]    0
11      flower     upper    top     white       (1,3]    0
12      flower     upper    top     white      (3,10]    3
13        leaf     lower bottom     white (0.01,0.03]    5
14        leaf     lower bottom     white  (0.03,0.1]    4
15        leaf     lower bottom     white   (0.1,0.3]    1
16        leaf     lower bottom     white     (0.3,1]    1
17        leaf     lower bottom     white       (1,3]    0
18        leaf     lower bottom     white      (3,10]    0
19        leaf     lower    top      grey (0.01,0.03]   10
20        leaf     lower    top      grey  (0.03,0.1]    1
21        leaf     lower    top      grey   (0.1,0.3]    0
22        leaf     lower    top      grey     (0.3,1]    0
23        leaf     lower    top      grey       (1,3]    0
24        leaf     lower    top      grey      (3,10]    0
25        leaf     upper bottom     white (0.01,0.03]    4
26        leaf     upper bottom     white  (0.03,0.1]    6
27        leaf     upper bottom     white   (0.1,0.3]    1
28        leaf     upper bottom     white     (0.3,1]    0
29        leaf     upper bottom     white       (1,3]    0
30        leaf     upper bottom     white      (3,10]    0
31        leaf     upper    top      blue (0.01,0.03]   10
32        leaf     upper    top      blue  (0.03,0.1]    0
33        leaf     upper    top      blue   (0.1,0.3]    0
34        leaf     upper    top      blue     (0.3,1]    0
35        leaf     upper    top      blue       (1,3]    1
36        leaf     upper    top      blue      (3,10]    0

(实际上,它不会像这样打印,因为这是一个 tbl,但您可以使用 print.data.frame 以旧方式打印一个 tbl。)

从这里提取您想要的信息应该很简单。

【讨论】:

  • 太棒了,效果很好。谢谢你。现在这让我对 dplyr 有所了解,我会去阅读文档,看看是否能找到教程。现在我看到了你的代码和解释,看起来并不那么令人生畏。
【解决方案2】:

首先定义一个带有因子名称的字符向量:

factors <- c("sample.type","leaf.side","canopy", "treatment")

然后使用此向量将hist() 函数应用于每个因子(假设数据存储在名为df 的数据框对象中):

res <- sapply(factors, function(factor) {
  lapply(split(df[, c("Feret", factor)], df[[factor]]), function(group) {
    hist(group$Feret, breaks = bins, plot = FALSE)
  })
}, simplify = FALSE)

您现在有一个列表,其中每个因素都有一个元素,每个元素又是一个列表,每个级别都有一个元素:

> names(res)
[1] "sample.type" "leaf.side"   "canopy"      "treatment"  
> names(res$sample.type)
[1] "flower" "leaf"
> res$sample.type$flower
$breaks
[1]  0.01  0.03  0.10  0.30  1.00  3.00 10.00

$counts
[1]  4 10  1  0  1  6

$density
[1] 9.09090909 6.49350649 0.22727273 0.00000000 0.02272727 0.03896104

$mids
[1] 0.020 0.065 0.200 0.650 2.000 6.500

$xname
[1] "group$Feret"

$equidist
[1] FALSE

attr(,"class")
[1] "histogram"
> 

您可以将其格式化为适合绘图的内容。

【讨论】:

  • 所以这就是使用 apply 的方法。非常感谢。
【解决方案3】:

如果我们对没有出现的 bin 不感兴趣,我们只需要:

df %>% 
  group_by(sample.type, leaf.side, canopy, treatment, groups = cut(Feret, bins)) %>% 
  summarise(freq =n())

输出:

   sample.type leaf.side canopy treatment      groups freq
1       flower     upper    top     green  (0.03,0.1]    6
2       flower     upper    top     green   (0.1,0.3]    1
3       flower     upper    top     green       (1,3]    1
4       flower     upper    top     green      (3,10]    3
5       flower     upper    top     white (0.01,0.03]    4
6       flower     upper    top     white  (0.03,0.1]    4
7       flower     upper    top     white      (3,10]    3
8         leaf     lower bottom     white (0.01,0.03]    5
9         leaf     lower bottom     white  (0.03,0.1]    4
10        leaf     lower bottom     white   (0.1,0.3]    1
11        leaf     lower bottom     white     (0.3,1]    1
12        leaf     lower    top      grey (0.01,0.03]   10
13        leaf     lower    top      grey  (0.03,0.1]    1
14        leaf     upper bottom     white (0.01,0.03]    4
15        leaf     upper bottom     white  (0.03,0.1]    6
16        leaf     upper bottom     white   (0.1,0.3]    1
17        leaf     upper    top      blue (0.01,0.03]   10
18        leaf     upper    top      blue       (1,3]    1

【讨论】:

  • 谢谢。我只是想知道如何处理零计数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
  • 1970-01-01
  • 2013-04-08
  • 1970-01-01
相关资源
最近更新 更多