适用于初学者。内容包括CSV文件的读取,整理合并表格,按需求分组并筛选所需数据并可视化。
使用到的数据:链接:https://pan.baidu.com/s/1yhzQSdquizLayXamM0wygg
提取码:3b7i
案例简介
用到的数据共4张表(cvs格式),为2003-2019年美国纽约市房地产交易数据。
NYC_HISTORICAL包含:交易ID,社区ID,地址,建筑类型,时间,价格,面积等;
BOROUGH包含:BOROUGH_ID和BOROUG名称;
BUILDING_CLASS包含:建筑ID和建筑类型等;
NEIGHBORHOOD 包含:街道ID和BOROUGH_ID等;
本案例需要根据ID整合数据,从中提取目标信息。
本章目标
任务1:过滤数据,使其仅包括您所选社区的住宅房地产。按年份分组,汇总数据,显示1平方英尺房地产的平均价格。列出结果。
任务2:数据是否显示了所有年份?如果一年显示不适用,为什么会发生这种情况?
任务3:过滤数据,为模型提供足够的信息(删除价格为0或平方英尺的字段)
任务4:将过滤后的数据按年份分组,并汇总数据以显示1平方英尺房地产的平均价格。列出结果。
将你选择的社区与附近的两个社区进行比较。列出数字。
任务5:制作一个比较三者的图。
开始:载入所需的包,并设置工作地址(也可以手动点击R上方工具栏的Session选择)。
library(lubridate) #year()
library(tidyverse) #(read_csv2)
setwd("C:/Users/10098/Desktop/AD571/AD571 a2") #Set Working Directory (设置工作地址)
读取所有csv文件。第四个NYC_HISTORICAL较大(150M),且用分号隔开,故用csv2读取
BOROUGH <- read.csv("BOROUGH.csv", header=TRUE)
BUILDING_CLASS <- read.csv("BUILDING_CLASS.csv", header=TRUE)
NEIGHBORHOOD <- read.csv("NEIGHBORHOOD.csv", header=TRUE)
NYC_HISTORICAL <- read_csv2("NYC_HISTORICAL.csv")
在NYC_HISTORICAL中创建年(因为要按年分组),并整合到一个数据框中。
合并表时,若同样列名均存在于两表,则 by = 'A' 即可。
若同样的列在不同表中不同名,则可用 by = c('A' = 'B')
select出所需数据,并filter选择的街道和类型
NYC_HISTORICAL <- mutate(NYC_HISTORICAL, Y = year(SALE_DATE))
NEIGHBORHOOD <- left_join(NEIGHBORHOOD,BOROUGH, by = 'BOROUGH_ID')
df <- NYC_HISTORICAL %>%
left_join(BUILDING_CLASS, by = c('BUILDING_CLASS_FINAL_ROLL' = 'BUILDING_CODE_ID')) %>%
left_join(NEIGHBORHOOD, by = 'NEIGHBORHOOD_ID') %>%
select(NEIGHBORHOOD_ID, SALE_DATE,SALE_PRICE,GROSS_SQUARE_FEET,TYPE,Y) %>%
filter(NEIGHBORHOOD_ID =='29', TYPE == 'RESIDENTIAL') %>%
group_by(Y)
注:这里用到的Pipe (%>%) , 此运算符将值或表达式的结果转发到下一个函数调用/表达式中。
接着计算平均价格(summarize会按照group进行计算,我们在上面按年份group过了)
AVERAGE_PRICE <- summarize(df, sum(SALE_PRICE) / sum(GROSS_SQUARE_FEET))
按照数据运行出来,发现2019是NA
这是因为数据里有空值,检查一下:
table(is.na(df$GROSS_SQUARE_FEET))
结果显示,确实有空值。
所以下一步,处理空值。在df的基础上得到df2。
【这里是直接粗暴的删去空值,以后可以使用更合适的处理方法】
df2 <- na.omit(df)
用df2再来一次(顺便改列名)
AVEPRICE_after <- summarize(df2, sum(SALE_PRICE)/ sum(GROSS_SQUARE_FEET))
names(AVEPRICE_after) <- c('Y', 'AVEPRICE_after')
结果就有了,2019不再是空值(平时要多注意数据中的空值)
接下来再选两个街道,和之前选的做比较。(数据的提取与上述方式一样,末尾加上了处理空值)
#BAY_RIDGE(16)
df3 <- NYC_HISTORICAL %>%
left_join(BUILDING_CLASS, by = c('BUILDING_CLASS_FINAL_ROLL' = 'BUILDING_CODE_ID')) %>%
left_join(NEIGHBORHOOD, by = 'NEIGHBORHOOD_ID') %>%
select(NEIGHBORHOOD_ID, SALE_DATE,SALE_PRICE,GROSS_SQUARE_FEET,TYPE,Y) %>%
filter(NEIGHBORHOOD_ID =='16', TYPE == 'RESIDENTIAL') %>%
group_by(Y)%>%
na.omit()
AVEPRICE_after16 <- summarize(df3, sum(SALE_PRICE)/ sum(GROSS_SQUARE_FEET))
names(AVEPRICE_after16) <- c('Y', 'AVEPRICE_after16')
#SUNSET_PARK(235)
df4 <- NYC_HISTORICAL %>%
left_join(BUILDING_CLASS, by = c('BUILDING_CLASS_FINAL_ROLL' = 'BUILDING_CODE_ID')) %>%
left_join(NEIGHBORHOOD, by = 'NEIGHBORHOOD_ID') %>%
select(NEIGHBORHOOD_ID, SALE_DATE,SALE_PRICE,GROSS_SQUARE_FEET,TYPE,Y) %>%
filter(NEIGHBORHOOD_ID =='235', TYPE == 'RESIDENTIAL') %>%
group_by(Y)%>%
na.omit()
AVEPRICE_after235 <- summarize(df4, sum(SALE_PRICE)/ sum(GROSS_SQUARE_FEET))
names(AVEPRICE_after235) <- c('Y', 'AVEPRICE_after235')
三组数据整合到一起
compare <- AVEPRICE_after %>%
left_join(AVEPRICE_after16, by = 'Y') %>%
left_join(AVEPRICE_after235, by = 'Y')
开始画图。与一般的图不同,要求同时显示三组数据的折线图,所以先处理一下。
将NEIGHBORHOOD_NAME放入。(改列名是为了方便合并)
draw29 <- mutate(AVEPRICE_after, NEIGHBORHOOD_NAME = 'BOROUGH_PARK')
names(draw29) <- c('YEAR','AVERAGE_PRICE','NEIGHBORHOOD_NAME')
draw16 <- mutate(AVEPRICE_after16, NEIGHBORHOOD_NAME = 'BAY_RIDGE')
names(draw16) <- c('YEAR','AVERAGE_PRICE','NEIGHBORHOOD_NAME')
draw235 <- mutate(AVEPRICE_after235, NEIGHBORHOOD_NAME = 'SUNSET_PARK')
names(draw235) <- c('YEAR','AVERAGE_PRICE','NEIGHBORHOOD_NAME')
draw <- draw29 %>%
full_join(draw16, BY= 'YEAR') %>%
full_join(draw235, BY= 'YEAR')
将数据整理成这样(注意第三列,画图时用来作为shape)
最后一步,画图
chart <- ggplot(draw, aes(x = YEAR ,
y = AVERAGE_PRICE,
color = NEIGHBORHOOD_NAME,
shape = NEIGHBORHOOD_NAME)) +
geom_point(size = 3) +
geom_line(lwd = 1) +
labs(x = 'YEAR', y = 'AVERAGE PRICE OF RECIDENTIAL')
大功告成!
案例源于波士顿大学,感谢教授Tara Kelly