【发布时间】: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
我有一个这样的数据集:
Users Age
1 2
2 7
3 10
4 3
5 8
6 20
如何将此数据集拆分为 3 个数据集,其中第一个包含年龄在 0-5 岁之间的所有用户,第二个是 6-10 岁,第三个是 11-15 岁?
【问题讨论】:
?split和?subset
您可以将split 与cut 组合在一行代码中执行此操作,而无需为不同的数据范围使用一堆不同的表达式进行子集化:
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]`
【讨论】:
首先,这是我的数据集:foo=data.frame(Users=1:6,Age=c(2,7,10,3,8,20))
这是您的第一个 0-5 岁数据集:subset(foo,Age<=5&Age>=0)
Users Age
1 1 2
4 4 3
这是 6-10 岁的第二个:subset(foo,Age<=10&Age>=6)
Users Age
2 2 7
3 3 10
5 5 8
您的第三个(使用 subset(foo,Age<=15&Age>=11))是空的 - 您的最后一个 Age 观察超过 15 个。
另请注意,5 和 6 或 10 和 11 之间的小数年龄(例如 5.1、10.5)将被排除,因为此代码非常符合您的问题。如果您希望 6 岁以下的人进入第一组,只需将该代码修改为 subset(foo,Age<6&Age>=0)。如果您希望在第二组中使用Age=5.1 的假设人员,则该组的代码为subset(foo,Age<=10&Age>5)。
【讨论】:
我们还可以使用 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 相当灵活。
【讨论】: