【问题标题】:How can I create a list of classes including zero-counts from data?如何从数据中创建包含零计数的类列表?
【发布时间】:2020-10-08 12:01:07
【问题描述】:

给定一些像x = 10.08506, 10.32809, ... 这样的随机数据,我怎样才能以有效的方式创建分类列表?结果(请参见下面的可重现示例)应如下所示

classes         n
(10,10.1]       3
(10.1,10.2]     1
(10.2,10.3]     0
(10.3,10.4]     2
(10.4,10.5]     3
(10.5,10.6]     0
(10.6,10.7]     0
(10.7,10.8]     1

这是一个可重现的示例,它显示了迄今为止最简单的方法:我可以摆脱 data.frame dffull_join 吗?也许,我也可以摆脱br, h

library(dplyr)
set.seed(1)
number_of_observations <- 10
nbr <- 10

x <- rnorm(n = number_of_observations, mean = 10.273, sd = 0.3)
br <- seq(from = ceiling(min(nbr*x)-1)/nbr, 
          to = floor(max(nbr*x)+1)/nbr, by = 1/nbr)
h <- hist(x, breaks = br)

df <- tibble(
  classes = h$mids)
df <- df %>% 
  mutate(classes = cut(classes, breaks = br)) %>%
  group_by(classes) %>%
  mutate(n = n()) %>%
  ungroup() %>%
  mutate(freq = n / sum(n)) %>%
  arrange(classes)

df2 <- tibble(
  classes = x)
df2 <- df2 %>% 
  mutate(classes = cut(classes, breaks = br)) %>%
  group_by(classes) %>%
  mutate(n = n()) %>%
  ungroup() %>%
  mutate(freq = n / sum(n)) %>%
  arrange(classes) %>%
  distinct()

df <- df %>% full_join(df2, by = "classes")
df$n.y[is.na(df$n.y)] <- 0

result <- df[, c("classes", "n.y")]
colnames(result) <- c("classes", "n")
result

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以使用seqcuttableas.data.frame 在单行中执行此操作:

    setNames(as.data.frame(table(cut(x, seq(10, 10.8, 0.1)))), c("classes", "n"))
    #>       classes n
    #> 1   (10,10.1] 3
    #> 2 (10.1,10.2] 1
    #> 3 (10.2,10.3] 0
    #> 4 (10.3,10.4] 2
    #> 5 (10.4,10.5] 3
    #> 6 (10.5,10.6] 0
    #> 7 (10.6,10.7] 0
    #> 8 (10.7,10.8] 1
    
    

    【讨论】:

    • 很好的答案:base-R,单行,通用,清晰!只是出于好奇:您何时真正使用/需要 dplyr 或 tidyverse?在 base-R 中似乎“几乎所有事情”都是可能的。
    • @Christoph 你几乎总是可以只使用基础 R,但是 tidyverse 使许多常见的数据操作任务变得更容易。我认为它非常适合枢轴和连接以及交互式使用。它还经常使代码更具可读性。但是,我经常看到人们将自己打结,试图让 tidyverse 做一些在基础 R 中微不足道的事情。我想知道两者并且不害怕在两者之间切换是关键。
    【解决方案2】:

    cut + table by @Allan Cameron 的方法是有效的。这是hist的另一种选择

    > list2DF(hist(x,breaks = seq(10, 10.8, 0.1), plot = FALSE))
      breaks counts density  mids xname equidist
    1   10.0      3       3 10.05     x     TRUE
    2   10.1      1       1 10.15     x     TRUE
    3   10.2      0       0 10.25     x     TRUE
    4   10.3      2       2 10.35     x     TRUE
    5   10.4      3       3 10.45     x     TRUE
    6   10.5      0       0 10.55     x     TRUE
    7   10.6      0       0 10.65     x     TRUE
    8   10.7      1       1 10.75     x     TRUE
    9   10.8      3       3 10.05     x     TRUE
    

    【讨论】:

    • 我从未听说过list2DF。看起来真的很有用 - 谢谢!
    【解决方案3】:

    我们可以使用findInterval

    setNames(as.data.frame(table(findInterval(x, seq(10, 10.8, 0.1)))), c("classes", "n"))
    

    【讨论】:

      猜你喜欢
      • 2023-01-04
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2018-08-31
      相关资源
      最近更新 更多