修改:修改模拟数据,以便价格意味着/中位数和邻居不会完美重叠。
我在数据框中有一个专栏,我们称之为Price。我只是在这里模拟数据:
a
和一组社区,我们称之为Hoods:
mydata = data.frame(index = rep(1:1000))
mydata$price[1:300] = rnorm(250, mean = 10000, sd = 1000)
mydata$price[301:550] = rnorm(250, mean = 25000, sd = 1000)
mydata$price[551:775] = rnorm(250, mean = 75000, sd = 1000)
mydata$price[776:1000] = rnorm(250, mean = 100000, sd = 1000)
然后我按中位数价格汇总邻域,以创建一个中间值。我想以中位数价格区分邻里。
mydata$hoods = factor(c(rep('hood1',250),rep('hood2',250),rep('hood3',250),rep('hood4',250)))
然后我创建了邻居中位数的剪切版本(在我的实际数据中有24个邻域)。如下所示:
agg <- aggregate(mydata$price, by = list(hoods), FUN = median))
然后我想要替换每个&#39; hood1&#39;在具有聚合价格标签的原始数据中,依此类推所有社区。例如,前250个记录将是“低”。我知道我可以制作一些嵌套的if语句,或者强力硬编码。有没有人知道我可以一次性更有效地分配所有值的方法,因为我可以将它用于大于1000条记录的数据集。非常感谢您提供的任何帮助。
在最终输出中,分类的邻居(&#39;低&#39;,&#39;媒体&#39;&#39;高&#39;)不一定与刚刚相同根据原始数据对价格进行cut_aggregates <- cut(agg$x, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))
,因为某些街区会有“低”,“中等”和“高”的组合。使用这种策略。我想首先根据其聚合对每个邻域进行分类,然后重新编码邻域。
答案 0 :(得分:1)
修改:方法1
mydata <- within(mydata, med <- ave(price, hoods, FUN = median) )
mydata$new_label <- cut(mydata$med, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))
# index price hoods med new_label
# 1 1 10084.756 hood1 10014.38 low
# 2 2 10226.460 hood1 10014.38 low
# 3 3 10432.556 hood1 10014.38 low
# 4 4 10558.065 hood1 10014.38 low
# 5 5 10059.755 hood1 10014.38 low
# 6 6 9885.359 hood1 10014.38 low
<强> Approach2:强>
由于agg$labs
对hoods
中mydata
的每个级别都不是唯一的,因此最好通过将hoods
的级别映射为一个循环来单独重新分配标签agg$labs
。
如果agg$labs
中的hoods
中mydata
的每个级别都有mydata$hoods <- factor( mydata$hoods, levels = agg$Group.1, labels = agg$labs )
中的唯一标签,则只需通过agg$labs
重新分配标签即可。但是,您在mydata$hoods <- as.character( mydata$hoods ) # convert factor to character
agg$labs <- as.character(agg$labs) # convert factor to character
for( i in seq_len( nrow( agg ) ) ) { # change labels for hoods in mydata
mydata[ mydata$hoods %in% agg$Group.1[ i ], "hoods" ] <- agg$labs[i]
}
mydata$hoods <- factor( mydata$hoods ) # convert hoods back to factor
unique(mydata$hoods) # output
# [1] low medium high
# Levels: high low medium
中有重复级别,因此您将按照以下步骤操作。
set.seed( 200 )
mydata = data.frame(index = rep(1:1000))
mydata$price[1:250] = rnorm(250, mean = 10000, sd = 1000)
mydata$price[251:500] = rnorm(250, mean = 25000, sd = 1000)
mydata$price[501:750] = rnorm(250, mean = 75000, sd = 1000)
mydata$price[751:1000] = rnorm(250, mean = 100000, sd = 1000)
mydata$hoods = factor(c(rep('hood1',250),rep('hood2',250),rep('hood3',250),rep('hood4',250)))
agg <- with(mydata, aggregate( price, by = list(hoods), FUN = median) )
agg$labs <- cut(agg$x, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))
agg
# Group.1 x labs
# 1 hood1 10014.38 low
# 2 hood2 25021.96 medium
# 3 hood3 74963.40 high
# 4 hood4 100019.88 high
数据:强>
agg
如果您在set.seed()
函数中选择其他种子,LINQ
中的数据会有所不同。
答案 1 :(得分:1)
执行此操作的一种非常简单的方法,可能是最快的方法是使用data.table
。
library(data.table)
# convert mydata into a data.table
setDT(mydata)
# calculate median price by hood
mydata[, med := median(price), by=hoods]
现在你可以:
# replace the original data of `hoods` with the new price labels
mydata[, hoods := cut(med, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))]
# or create new price labels in a new column
mydata[, new_col := cut(med, breaks = c(0, 25000, 70000, 110000), labels = c('low','medium','high'))]
最后,如果您只需要每个引擎盖的摘要表:
mydata[, (med = median(price)), by=.(hoods, new_col)]
> hoods my_cut V1
> 1: hood1 low 9916.564
> 2: hood2 low 24696.864
> 3: hood3 high 74749.481
> 4: hood4 high 99852.744