我有一组房地产数据。我正在尝试在市场组(标记为 DOM_Groups)上创建一个新的天数列,并将它们分组为 15 天的时间间隔(即 0-14、15-29 等)。然后,我尝试通过观察计数和每个 15 天组的平均销售价格来summarize()
这些分组。
我正在使用 cut()
函数试图将我的 DOM_Groups 分成这 15 天的间隔。在我导入的基础电子表格中,包含上市天数的列在每个单元格中都有一个独特的观察值,并且该列中的数据是数字整数......没有小数,没有负数。
当我运行以下代码时,tibble 输出没有正确分组,它包含一个带小数的负数,这在我的数据集中不存在。我不知道该怎么做才能纠正这个问题。
gibbsMkt %>%
mutate(DOM_Groups = cut(DOM, breaks = 15, dig.lab = 2)) %>%
filter(Status == "SOLD") %>%
group_by(DOM_Groups) %>%
summarize(numDOM = n(),
avgSP = mean(`Sold Price`, na.rm = TRUE))
The tibble output I get is this:
DOM_Groups numDOM avgSP
<fct> <int> <dbl>
1 (-0.23,16] 74 561675.
2 (16,31] 18 632241.
3 (31,47] 11 561727.
4 (47,63] 8 545862.
5 (63,78] 7 729286.
6 (78,94] 6 624167.
7 (1.4e+02,1.6e+02] 2 541000
8 (1.6e+02,1.7e+02] 1 535395
此外,对于 tibble 中的第 7 行和第 8 行,最大的数字是 164,所以我也不明白为什么这些行被转换为科学记数法。
当我使用 Excel 数据透视表时,我得到了想要在 R 中重现的输出,如下所示:
如何使用正确的代码在 R 中重现这个?
答案 0 :(得分:3)
cut(x, breaks = 15)
表示 x
将被切割成 15 个间隔——它无法猜测您想要从 0 开始到 150 结束的 15 个单位的间隔。这在 {{1} 的文档中}:
?cut
一个包含两个或多个唯一切割点的数字向量或一个数字(大于或等于 2),给出 x 被切割成的区间数。
您需要为每个间隔定义自己的开始和结束,例如:
breaks
但是,如果设置正确,则可以定义间隔并同时制作标签。
seq(0, max(x), 15)
# [1] 0 15 30 45 60 75 90 105 120 135 150
cut(x, seq(0, max(x), 15))
您的另一个问题是“我为什么会得到负数”,正如我所提到的,这并不意味着您的数据中有负数——这些只是通过对您的数据使用 set.seed(1)
x <- floor(runif(500, 0, 164))
from <- seq(0, max(x), 15)
to <- from + 15 - 1
labs <- sprintf('%s-%s', from, to)
# [1] "0-14" "15-29" "30-44" "45-59" "60-74" "75-89" "90-104" "105-119" "120-134" "135-149" "150-164"
data.frame(table(cut(x, c(from, Inf), right = FALSE)), labels = labs)
# Var1 Freq labels
# 1 [0,15) 35 0-14
# 2 [15,30) 57 15-29
# 3 [30,45) 45 30-44
# 4 [45,60) 44 45-59
# 5 [60,75) 57 60-74
# 6 [75,90) 55 75-89
# 7 [90,105) 33 90-104
# 8 [105,120) 47 105-119
# 9 [120,135) 40 120-134
# 10 [135,150) 39 135-149
# 11 [150,Inf) 48 150-164
DOM_Groups <- cut(x, c(from, Inf), labs, right = FALSE)
data.frame(table(DOM_Groups))
# DOM_Groups Freq
# 1 0-14 35
# 2 15-29 57
# 3 30-44 45
# 4 45-59 44
# 5 60-74 57
# 6 75-89 55
# 7 90-104 33
# 8 105-119 47
# 9 120-134 40
# 10 135-149 39
# 11 150-164 48
生成的标签。
这些是 breaks = 15
cut.default
使用之前的 if (length(breaks) == 1L) {
if (is.na(breaks) || breaks < 2L)
stop("invalid number of intervals")
nb <- as.integer(breaks + 1)
dx <- diff(rx <- range(x, na.rm = TRUE))
if (dx == 0) {
dx <- if (rx[1L] != 0)
abs(rx[1L])
else 1
breaks <- seq.int(rx[1L] - dx/1000, rx[2L] + dx/1000,
length.out = nb)
}
else {
breaks <- seq.int(rx[1L], rx[2L], length.out = nb)
breaks[c(1L, nb)] <- c(rx[1L] - dx/1000, rx[2L] +
dx/1000)
}
和 x
,您可以看到否定是如何引入的:
breaks = 15
答案 1 :(得分:1)
这是我的 santoku
包的简单解决方案:
library(santoku)
gibbsMkt %>%
mutate(DOM_Groups = chop_width(DOM, 15, labels = lbl_dash("-")))
# then proceed as before
如果您想以特定数字开始间隔,您可以将 start
参数用于 chop_width
。