从一个因子创建有效范围并在 R 中应用另一个因子范围

问题描述 投票:0回答:1

我有一个包含 2 列的 csv 文件,第一列是代表容器尺寸范围的因素类别,第二列是属于该尺寸类别的容器类别。我需要使用这些数据来填写一个包含不同既定容器尺寸范围的新表格。例如:我的初始原始数据分为两列;

dat.start<-data.frame(category=c(rep("1-10",3), rep("11-20",3), rep("21-30",3), rep("32-40",3), rep("41-50",3), rep("51-59",3)), class=rep(c("a","b","c"),6))

当我按类别汇总时,例如

ag.dat<-aggregate(class ~ category, data = dat.start, length)

你会看到我得到一个 df 结构

str(ag.dat)
由 chr 列和 int 列组成。

下一个问题是我需要将那些容器尺寸的频率分配到一个新的、预定的容器尺寸类别表中,这些类别与第一个不同。例如,下面是基于原始 dat.start 数据的新尺寸类别和容器类别的频率

dat.end<-data.frame(category=c("1-20", "21-50", ">50"), class=c(6, 9, 3))

所以我的问题是如何从 dat.start 到 dat.end?我的第一个想法是以某种方式拆分 chr 字符串类别并创建可以用数字解释的新 dat.start 和 dat.end 范围,例如

cut
产生的内容。但是当谈到下一步实际创建基于新类别的容器类别频率时,我陷入了一片空白。另外,将 chr 字符串范围转换为数字范围也难倒了我。

我认为我在网上找到的最接近的解决方案是在这里; 从有效范围列表中识别匹配范围

但这看起来像是为 Python/Pandas 编写的,我需要在 R 中完成。谢谢。

r range categories
1个回答
1
投票

如果您将“类别”分成两列,您可以进行数值比较,例如

library(tidyverse)

dat.start<-data.frame(category=c(rep("1-10",3), rep("11-20",3), rep("21-30",3), rep("32-40",3), rep("41-50",3), rep("51-59",3)), class=rep(c("a","b","c"),6))

dat.start
#>    category class
#> 1      1-10     a
#> 2      1-10     b
#> 3      1-10     c
#> 4     11-20     a
#> 5     11-20     b
#> 6     11-20     c
#> 7     21-30     a
#> 8     21-30     b
#> 9     21-30     c
#> 10    32-40     a
#> 11    32-40     b
#> 12    32-40     c
#> 13    41-50     a
#> 14    41-50     b
#> 15    41-50     c
#> 16    51-59     a
#> 17    51-59     b
#> 18    51-59     c

dat.end<-data.frame(category=c("1-20", "21-50", ">50"), class=c(6, 9, 3))

dat.end
#>   category class
#> 1     1-20     6
#> 2    21-50     9
#> 3      >50     3

dat.start %>%
  separate(category, into = c("min", "max"), sep = "-") %>%
  mutate(category = case_when(max <= 20 ~ "1-20",
                              min > 20 & max <= 50 ~ "21-50",
                              min > 50 ~ ">50")) %>%
  summarise(class = n(), .by = category)
#>   category class
#> 1     1-20     6
#> 2    21-50     9
#> 3      >50     3

或者另一种可能的方法是使用“查找”表,例如

lookup_table <- setNames(c("1-20", "1-20", "21-50",
                           "21-50", "21-50", ">50"),
                         unique(dat.start$category))
lookup_table
#>    1-10   11-20   21-30   32-40   41-50   51-59 
#>  "1-20"  "1-20" "21-50" "21-50" "21-50"   ">50"

dat.start %>%
  mutate(category = recode(category, !!!lookup_table)) %>%
  summarise(class = n(), .by = category)
#>   category class
#> 1     1-20     6
#> 2    21-50     9
#> 3      >50     3

创建于 2023-03-07 与 reprex v2.0.2

对于此类任务,有许多不同的方法可以使用查找表,有关更多方法/示例,请参阅Canonical tidyverse method to update some values of a vector from a look-up table

© www.soinside.com 2019 - 2024. All rights reserved.