【问题标题】:How do I split a data frame based on range of column values in R?如何根据 R 中的列值范围拆分数据框?
【发布时间】:2025-12-31 20:00:01
【问题描述】:

我有一个这样的数据集:

Users   Age
1        2
2        7
3        10
4        3
5        8
6        20

如何将此数据集拆分为 3 个数据集,其中第一个包含年龄在 0-5 岁之间的所有用户,第二个是 6-10 岁,第三个是 11-15 岁?

【问题讨论】:

  • ?split?subset

标签: r split subset


【解决方案1】:

您可以将splitcut 组合在一行代码中执行此操作,而无需为不同的数据范围使用一堆不同的表达式进行子集化:

split(dat, cut(dat$Age, c(0, 5, 10, 15), include.lowest=TRUE))
# $`[0,5]`
#   Users Age
# 1     1   2
# 4     4   3
# 
# $`(5,10]`
#   Users Age
# 2     2   7
# 3     3  10
# 5     5   8
# 
# $`(10,15]`
# [1] Users Age  
# <0 rows> (or 0-length row.names)

cut 根据指定的断点拆分数据,split 根据提供的类别拆分数据框。如果将此计算的结果存储到名为l 的列表中,则可以使用l[[1]]l[[2]]l[[3]] 或更详细的方式访问较小的数据帧:

l$`[0,5]`
l$`(5,10]`
l$`(10, 15]`

【讨论】:

    【解决方案2】:

    首先,这是我的数据集:foo=data.frame(Users=1:6,Age=c(2,7,10,3,8,20))

    这是您的第一个 0-5 岁数据集:subset(foo,Age&lt;=5&amp;Age&gt;=0)

      Users Age
    1     1   2
    4     4   3
    

    这是 6-10 岁的第二个:subset(foo,Age&lt;=10&amp;Age&gt;=6)

      Users Age
    2     2   7
    3     3  10
    5     5   8
    

    您的第三个(使用 subset(foo,Age&lt;=15&amp;Age&gt;=11))是空的 - 您的最后一个 Age 观察超过 15 个。

    另请注意,5 和 6 或 10 和 11 之间的小数年龄(例如 5.1、10.5)将被排除,因为此代码非常符合您的问题。如果您希望 6 岁以下的人进入第一组,只需将该代码修改为 subset(foo,Age&lt;6&amp;Age&gt;=0)。如果您希望在第二组中使用Age=5.1 的假设人员,则该组的代码为subset(foo,Age&lt;=10&amp;Age&gt;5)

    【讨论】:

      【解决方案3】:

      我们还可以使用 data.table 包中的 between 函数。

      # Create a data frame
      dat <- data.frame(Users = 1:7, Age = c(2, 7, 10, 3, 8, 12, 15))
      
      # Convert the data frame to data table by reference
      # (data.table is also a data.frame)
      setDT(dat)
      
      # Define a list with the cut pairs
      cuts <- list(c(0, 5), c(6, 10), c(11, 15))
      
      # Cycle through dat and cut it into list of data tables by the values in Age
      # matching the defined cuts
      lapply(X = cuts, function(i) {
        dat[between(x = dat[ , Age], lower = i[1], upper = i[2])]
      })
      

      输出:

      [[1]]
         Users Age
      1:     1   2
      2:     4   3
      
      [[2]]
         Users Age
      1:     2   7
      2:     3  10
      3:     5   8
      
      [[3]]
         Users Age
      1:     6  12
      2:     7  15
      

      许多其他事情都是可能的,包括按组进行,data.table 相当灵活。

      【讨论】: