如何使用dplyr对x中的元素进行分组,计算y间隔频率的数量?

7
x <- c('a', 'v', 'c', 'a', 'd', 'e', 'g', 'f', 'h', 'y', 'u', 'r', 's', 'w', 's', 'd', 'g', 'j', 'u', 'r', 's', 's', 's', 'v', 'b', 'g', 'e', 'w', 's', 'd', 'g', 'h', 'j', 'i', 't', 'e', 'w', 'w', 'q', 'q', 'd', 'v', 'b', 'm', 'm', 'k', 'l', 'u', 'p', 'o', 'r', 't', 'n', 'e', 'w', 'w', 'j', 'f', 'c', 'g', 'h', 't', 'r', 'd', 'e', 'w', 'w', 'w', 'z', 'f', 'g', 'f', 'h', 'h', 'y', 'r', 'f', 'f', 'l') y <- sample(1:40, 79, replace=T) y 1 38 18 19 19 37 38 26 4 32 23 11 24 36 15 22 19 6 24 13 36 2 26 35 39 8 33 20 19 23 28 5 17 40 26 18 21 [37] 35 23 27 12 3 33 16 32 11 19 4 5 8 19 5 19 33 33 33 13 12 32 21 4 14 8 28 34 33 22 34 19 39 23 6 8 [73] 37 17 21 16 38 15 36

enter image description here

我有两个变量'x'和'y'。在'x'中有多个观察实例。对应于'x'中的每个观察值,都有相应的'y'值。

我想要实现对'y'值进行分组和分区间的操作。

换句话说,每个字母出现的次数将被划分为不同的间隔,这些间隔是根据每个字母在其出现中被赋予的值来确定的。

例如:

enter image description here

由于我在此处无法找到更好的输入方式,因此无法正确地表示表格。

希望我的意思清楚了。如果需要,我会尝试重新陈述它。 非常感谢您的帮助。

2个回答

12
使用进行数据操作
library(dplyr)
library(tidyr)

res <- tally(group_by(df, x, y=cut(y, breaks=seq(0,40, by=10)))) %>% 
                                                        ungroup() %>%
                                                         spread(y,n, fill=0)

或者使用data.table

library(data.table)
res1 <- dcast.data.table(setDT(df)[,list(.N), 
           by=list(x, y1=cut(y, breaks=seq(0,40, by=10)))],
                            x~y1, value.var="N", fill=0L)

all.equal(as.data.frame(res), as.data.frame(res1))
#[1] TRUE

注意:在cut中有一个label参数,如果您想将column标题设置为freq0-10等,请使用该参数。
 tally(group_by(df, x, y=cut(y,breaks=seq(0,40, by=10),
      labels=paste0("freq", c("0-10", "10-20", "20-30", "30-40")))))  %>%
                                                            ungroup() %>%
                                                            spread(y,n, fill=0) %>%
                                                            head(2)

  #   x freq0-10 freq10-20 freq20-30 freq30-40
  #1 a        0         1         1         0
  #2 b        1         1         0         0

数据

 df <-  structure(list(x = structure(c(1L, 22L, 3L, 1L, 4L, 5L, 7L, 6L, 
 8L, 24L, 21L, 18L, 19L, 23L, 19L, 4L, 7L, 10L, 21L, 18L, 19L, 
 19L, 19L, 22L, 2L, 7L, 5L, 23L, 19L, 4L, 7L, 8L, 10L, 9L, 20L, 
 5L, 23L, 23L, 17L, 17L, 4L, 22L, 2L, 13L, 13L, 11L, 12L, 21L, 
 16L, 15L, 18L, 20L, 14L, 5L, 23L, 23L, 10L, 6L, 3L, 7L, 8L, 20L, 
 18L, 4L, 5L, 23L, 23L, 23L, 25L, 6L, 7L, 6L, 8L, 8L, 24L, 18L, 
 6L, 6L, 12L), .Label = c("a", "b", "c", "d", "e", "f", "g", "h", 
 "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", 
 "v", "w", "y", "z"), class = "factor"), y = c(12L, 9L, 29L, 21L, 
 27L, 37L, 12L, 31L, 33L, 11L, 25L, 15L, 27L, 27L, 13L, 37L, 8L, 
 2L, 21L, 6L, 4L, 23L, 30L, 6L, 9L, 28L, 4L, 24L, 26L, 2L, 13L, 
 10L, 15L, 6L, 38L, 9L, 30L, 26L, 28L, 39L, 19L, 16L, 11L, 9L, 
 2L, 4L, 16L, 15L, 11L, 14L, 19L, 35L, 19L, 29L, 22L, 40L, 19L, 
 12L, 7L, 6L, 20L, 10L, 12L, 6L, 30L, 13L, 38L, 39L, 30L, 20L, 
 6L, 9L, 1L, 40L, 26L, 14L, 23L, 33L, 2L)), .Names = c("x", "y"
 ), row.names = c(NA, -79L), class = "data.frame")

嗯,我对 dplyr 一无所知,因此基于 Ananda 的建议提供了解决方案。有趣的是,如果有人能想出更简洁的 dplyr 解决方案会更加有趣。 - tchakravarty
感谢akrun提供的解决方案。由于我想更清楚地理解它,如果我的间隔不是均匀的,比如0-13、13-30、30及以上,我该怎么做呢? - user3563667
@user3563667,你可以指定间隔为c(0,13,30,..),而不是使用seq。我只是根据你的示例使用了seq - akrun
如果上限不清楚,那么c(0,13,30,max(y))表示可能有效。但是有没有其他方法可以不使用max(y)来编写它? - user3563667
@user3563667 你可以使用“-Inf,Inf”,但这取决于你想要的结果。 - akrun
@akrun 因为这个被踩?不可能。我在回答中错过了tally。好的提醒。现在是时候阅读data.table的答案了。+1。 - jazzurro

2

根据Ananda Mahto的建议,这里使用bycuttable实现。

x = c('a','v','c','a','d','e','g','f','h','y','u','r','s','w','s','d','g','j',
      'u','r','s','s','s','v','b','g','e','w','s','d','g','h','j','i','t','e',
      'w','w','q','q','d','v','b','m','m','k','l','u','p','o','r','t','n','e',
      'w','w','j','f','c','g','h','t','r','d','e','w','w','w','z','f','g','f',
      'h','h','y','r','f','f','l')
y = sample(1:40, 79, replace = TRUE)
dfX = data.frame(x, y)

t(sapply(
  by(
    dfX$y, list(dfX$x), cut, breaks = c(0, 10, 20, 30, 40)),
  table)
  )

这里是输出结果:

> t(sapply(by(dfX$y, list(dfX$x), cut, breaks = c(0, 10, 20, 30, 40)), table))
  (0,10] (10,20] (20,30] (30,40]
a      0       0       0       2
b      0       0       2       0
c      0       1       0       1
d      0       2       2       1
e      2       1       1       1
f      0       4       1       1
g      3       0       1       2
h      2       0       2       1
i      0       0       0       1
j      1       2       0       0
k      1       0       0       0
l      0       1       1       0
m      0       1       0       1
n      0       0       0       1
o      0       1       0       0
p      1       0       0       0
q      0       1       1       0
r      2       1       0       2
s      0       2       0       4
t      1       1       0       1
u      1       0       1       1
v      2       0       0       1
w      6       0       3       0
y      0       1       0       1
z      1       0       0       0

在这个逻辑中,数字10属于区间(0,10)还是(10,20)? - user3563667
这是使用标准的数学符号表示:表示开放(非包含),而 ]表示封闭(包含)。因此,10包含在第一个分区中。 - tchakravarty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接