项目背景

此次分析是启发于在知乎看到的一篇文章,文章的结果中,数据分析师需要的技能没有R语言,抱着证实R语言这款工具的想法,以及希望了解当前企业对数据分析岗位的需求,开始了一次针对招聘网站的数据分析岗位招聘数据的分析与挖掘实践,避免自己所学习的方向与企业实际需求脱轨。

目的

  1. 了解企业当前需要什么样的数据分析人才,以及应该具备的能力和素质。
  2. 分析的结果为自己今后的学习和求职提供指导,也为正在学习数据分析和找工作的朋友们提供一定的参考价值。

分解问题

  1. 不同地区,数据分析岗位的需求分布以及对应的薪资分布
  2. 不同经验,数据分析岗位的需求分布以及对应的薪资分布
  3. 不同学历,数据分析岗位的需求分布以及对应的薪资分布
  4. 不同企业规模,数据分析岗位的需求分布以及对应的薪资分布
  5. 探索数据分析岗位对应的工具型技能与对应的薪资水平
  6. 探索数据分析岗位对应非工具型能力的需求

数据集定义

需要定义如下数据字典(预期希望得到的数据)

表1

字段 描述 用途
id 唯一标识 与数据库表主键功能类似,用于处理表关联
title 岗位名称 作为岗位的标识,与雇主和岗位描述组合成唯一标识
company 公司名称 作为雇主的标识
salary 平均月薪(k) 用于平均月薪的分析
city 工作所在城市 用于分析地域
scale 规模 用于区别企业的指标
phase 融资/发展阶段 用于区别企业的指标
experience 职位经验要求 分析工作经验的影响
education 学历要求 分析学历的影响
description 职位描述 用于文本挖掘,做岗位需求技能分析

表2

字段 描述 用途
id 标识 与数据库表外键功能类似,用于处理表关联
keyword 关键词 表示一个数据分析工具或技能

数据获取

  • 数据来源:拉勾网
  • 数据范围:互联网行业、数据分析岗位
  • 数据集:全国数据分析岗位招聘信息数据集(采集样本量:449)
  • 工具:爬虫
  • 时间:所有数据截止2018年3月12日
  • 数据集下载地址:链接:https://pan.baidu.com/s/1Bz7mA_dnvD1MGTVrZKyhPA 密码:layp

数据处理

1、初始数据加载

#readxl包的read_excel函数
library(readxl)
#数据加载
#提取所需分析的数据
CN.df <- read_excel("CN_lagou_jobdata.xlsx",1)
CN.df <- CN.df[,c("title","salary","experience","education","campany","scale","scale2","description","phase","city")]

#观察数据,分类变量不是因子的格式,且存在不需要的字符
str(CN.df)
## Classes 'tbl_df', 'tbl' and 'data.frame':    449 obs. of  10 variables:
##  $ title      : chr  "数据分析师" "数据分析师" "数据分析" "数据分析师" ...
##  $ salary     : chr  "10k-20k" "12k-20k" "15k-30k" "15k-25k" ...
##  $ experience : chr  "经验5-10年 /" "经验不限 /" "经验1-3年 /" "经验1-3年 /" ...
##  $ education  : chr  "本科及以上 /" "本科及以上 /" "本科及以上 /" "本科及以上 /" ...
##  $ campany    : chr  "\n                                    Gridsum 国双\n" "\n                                    酷家乐\n" "\n                                    快看漫画\n" "\n                                    作业盒子\n" ...
##  $ scale      : chr  "\n                 500-2000人\n                规模\n" "\n                GGV、IDG、经纬、线性资本、云启资本、赫斯特资本(B轮),IDG(A轮)\n                投资机构\n" "\n                Coatue Management、华人文化产业投资基金、襄禾资本等(D轮及以上)\n                投资机构\n" "\n                联想之星(天使轮),好未来、刘强东、奶茶妹妹、联想之星(A轮),贝塔斯曼领投(B轮)\n                投资机构\n" ...
##  $ scale2     : chr  "\n                \n                                http://www.gridsum.com\n                公司主页\n" "\n                 500-2000人\n                规模\n" "\n                 150-500人\n                规模\n" "\n                 500-2000人\n                规模\n" ...
##  $ description: chr  "\n        岗位职责:\n利用国双自有的一系列监测工具采集、分析客户网站、APP、媒体投放所生成的大数据。\n2. 学会并"| __truncated__ "\n        岗位描述:\n1、负责酷家乐业务数据分析,包括报表设计、数据建模等;针对产品和用户,有能力在海量数据中进"| __truncated__ "\n        工作职责:\n1、负责运营业务的产品以及运营数据指标的搭建\n2、监控运营相关数据,能从数据异动中发现问题"| __truncated__ "\n        岗位职责:\n1、负责分析和解释产品试验,市场活动等的结果,为产品改进,推广试验等提供数据支持;\n2、负"| __truncated__ ...
##  $ phase      : chr  "上市公司\n" "D轮及以上\n" "D轮及以上\n" "C轮\n" ...
##  $ city       : chr  "/北京 /" "/杭州 /" "/北京 /" "/北京 /" ...

2、识别缺失值

#识别缺失值
#VIM包的aggr函数来识别
library(VIM)
aggr(CN.df,prop=TRUE,numbers=TRUE)

结果显示,我们关心的数据不存在什么缺失值,这对于数据处理来说是极好的信息

3、处理数据

#zoo包的index函数
library(zoo)
#定义数据清洗函数
cleaning <- function(my.data){
  #删除重复值,结果显示还有443行数据
  my.data <- my.data[!duplicated(my.data[c("title","campany","description")]),]
  #计算平均月薪
  min_salary <- as.numeric(sub("([0-9]*).*","\\1",my.data$salary))
  max_salary <- as.numeric(sub(".*-([0-9]*).*","\\1",my.data$salary))
  my.data$avg_salary <- (max_salary + min_salary)/2
  #清理字符串中的不需要的字符
  #并将需要分析的字符变量转化为因子,并对部分因子重新编码
  my.data$city <- factor(gsub("[/ ]*","",my.data$city))
  
  my.data$experience <- gsub("经验|[/ ]*","",my.data$experience)
  my.data$experience[my.data$experience %in% c("不限","应届毕业生")] <- "1年以下"
  my.data$experience <- factor(my.data$experience,
                                levels=c("1年以下","1-3年","3-5年","5-10年","10年以上"))
  
  #这里的学历:“大专”,“本科”,“硕士”都表明是要求该学历“及以上”
  my.data$education <- gsub("学历|及以上|[/ ]*","",my.data$education)
  my.data$education[my.data$education=="不限"] <- "大专"
  my.data$education <- factor(my.data$education,levels=c("大专","本科","硕士"))
  
  my.data$phase <- factor(gsub("[\n]*","",my.data$phase),levels =
                        c("不需要融资","未融资","天使轮","A轮",
                          "B轮","C轮","D轮及以上","上市公司"))
  my.data$campany <- gsub("[\n| ]*","",my.data$campany)
  my.data$scale <- factor(gsub(".*(少于15人|15-50人|50-150人|150-500人|500-2000人|2000人以上).*",
                               "\\1",paste(my.data$scale,my.data$scale2)),
                          levels =c("少于15人","15-50人","50-150人",
                          "150-500人","500-2000人","2000人以上")) 
  my.data$id <- index(my.data)
  my.data <- droplevels(subset(my.data,select=-scale2))
  return(my.data)
}
#清洗数据,得到清洗后的数据
CN.clean <- cleaning(CN.df)
str(CN.clean)
## Classes 'tbl_df', 'tbl' and 'data.frame':    442 obs. of  11 variables:
##  $ title      : chr  "数据分析师" "数据分析师" "数据分析" "数据分析师" ...
##  $ salary     : chr  "10k-20k" "12k-20k" "15k-30k" "15k-25k" ...
##  $ experience : Factor w/ 4 levels "1年以下","1-3年",..: 4 1 2 2 3 2 3 3 3 3 ...
##  $ education  : Factor w/ 3 levels "大专","本科",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ campany    : chr  "Gridsum国双" "酷家乐" "快看漫画" "作业盒子" ...
##  $ scale      : Factor w/ 5 levels "15-50人","50-150人",..: 4 4 3 4 3 3 5 4 4 5 ...
##  $ description: chr  "\n        岗位职责:\n利用国双自有的一系列监测工具采集、分析客户网站、APP、媒体投放所生成的大数据。\n2. 学会并"| __truncated__ "\n        岗位描述:\n1、负责酷家乐业务数据分析,包括报表设计、数据建模等;针对产品和用户,有能力在海量数据中进"| __truncated__ "\n        工作职责:\n1、负责运营业务的产品以及运营数据指标的搭建\n2、监控运营相关数据,能从数据异动中发现问题"| __truncated__ "\n        岗位职责:\n1、负责分析和解释产品试验,市场活动等的结果,为产品改进,推广试验等提供数据支持;\n2、负"| __truncated__ ...
##  $ phase      : Factor w/ 8 levels "不需要融资","未融资",..: 8 7 7 6 6 5 8 7 6 8 ...
##  $ city       : Factor w/ 23 levels "北京","常州",..: 1 10 1 1 10 15 1 1 10 1 ...
##  $ avg_salary : num  15 16 22.5 20 15 15 15 15 15 20 ...
##  $ id         : int  1 2 3 4 5 6 7 8 9 10 ...

4、文本挖掘 采用jiebaR分词器进行文本挖掘

声明: 笔者测试过jiebaR的关键词分词器,测试的结果发现SQL,Python等词在jiebaR词典中的IDF值均为11.7392,但“R”这个字符无论如何(即使自定义了用户字典,或者在idf字典中添加R的idf值)都无法被分词器识别为关键词,猜测可能是默认R的词性标注或者算法实现方法的原因。但因为R是数据分析师的重要工具,识别不出来是不可容忍的,因此要求出路。

为词频,IDF为逆文档率(词的权重),因此TF-IDF=TF*IDF为衡量是否关键词的指标,若控制IDF,则TF-IDF的值与TF值成正比关系,简单来说TF值可以代替TF-IDF值。 由于此次分析的是数据分析师的工具和技能,因此只考虑SQL,PYTHON,R,SAS等常用且类似的词的分析,又因为该类词在jiebaR分词器识别出来的IDF值均是同级别的(即使可能存在有差异也在此假设其等值),因此这部分词汇的关键指标的衡量可以简化为出现的词频,即TF值,这个可以通过jiebaR的默认分词器来处理可得。

挖掘思路:

1、工具型技能关键词挖掘->分析岗位技能需求

2、非工具型的技能或理论知识关键词挖掘->分析岗位非工具型技能需求

library(jiebaR)
library(jiebaRD)
library(zoo)
library(plyr)
source("myfun.R")
#提取技能型关键词
#采用默认jiebaR分词器
engine <- worker(user = "user_dict.txt")
#分词,并删除无关的词汇
word.lis <- lapply(CN.clean$description, function(x){
  v <- gsub("[\u4e00-\u9fa5|0-9|\\.|\\-]","",segment(x,engine))
  v <- v[v!=""]
  return(v)
})
#将所有分出来的词转化为大写,消除大小写差异
segWords <- toupper(unlist(word.lis))
stopwords <- toupper(readLines("stopwords.txt"))
#过滤停词,由于文本可能会存在其他高频的词汇,把不需要的词去除,如(and,of…)
#此处确保我要得到的前20个关键技能是正确的数据分析技能
segWords<-filter_segment(segWords,stopwords)

#形成词频表(数据框格式),获取前15个技能关键词
top15.df <- top.freq(segWords,topn = 15)


#生成有id和keyword构建的数据框,id对应cleandata数据集的id(即数据字典表1和表2的关系)
id <- NULL
keyword <- NULL
for (i in index(word.lis)) {
  id <- c(id,rep(i,length(word.lis[[i]])))
  keyword <- c(keyword,word.lis[[i]])
}
keyword.df <- data.frame("id"=id,"keyword"=toupper(keyword))
keyword.df <- droplevels(keyword.df[keyword.df$keyword %in% top15.df$x,])

str(keyword.df)
## 'data.frame':    1791 obs. of  2 variables:
##  $ id     : int  1 1 1 2 2 2 2 4 4 4 ...
##  $ keyword: Factor w/ 15 levels "BI","EXCEL","HADOOP",..: 2 9 15 2 15 3 10 15 10 11 ...
#合并两个数据集(表之间的内连接,类似sql语句的inner jion)
merge.df <- merge(CN.clean,keyword.df,by="id")
str(merge.df)
## 'data.frame':    1791 obs. of  12 variables:
##  $ id         : int  1 1 1 2 2 2 2 4 4 4 ...
##  $ title      : chr  "数据分析师" "数据分析师" "数据分析师" "数据分析师" ...
##  $ salary     : chr  "10k-20k" "10k-20k" "10k-20k" "12k-20k" ...
##  $ experience : Factor w/ 4 levels "1年以下","1-3年",..: 4 4 4 1 1 1 1 2 2 2 ...
##  $ education  : Factor w/ 3 levels "大专","本科",..: 2 2 2 2 2 2 2 2 2 2 ...
##  $ campany    : chr  "Gridsum国双" "Gridsum国双" "Gridsum国双" "酷家乐" ...
##  $ scale      : Factor w/ 5 levels "15-50人","50-150人",..: 4 4 4 4 4 4 4 4 4 4 ...
##  $ description: chr  "\n        岗位职责:\n利用国双自有的一系列监测工具采集、分析客户网站、APP、媒体投放所生成的大数据。\n2. 学会并"| __truncated__ "\n        岗位职责:\n利用国双自有的一系列监测工具采集、分析客户网站、APP、媒体投放所生成的大数据。\n2. 学会并"| __truncated__ "\n        岗位职责:\n利用国双自有的一系列监测工具采集、分析客户网站、APP、媒体投放所生成的大数据。\n2. 学会并"| __truncated__ "\n        岗位描述:\n1、负责酷家乐业务数据分析,包括报表设计、数据建模等;针对产品和用户,有能力在海量数据中进"| __truncated__ ...
##  $ phase      : Factor w/ 8 levels "不需要融资","未融资",..: 8 8 8 7 7 7 7 6 6 6 ...
##  $ city       : Factor w/ 23 levels "北京","常州",..: 1 1 1 10 10 10 10 1 1 1 ...
##  $ avg_salary : num  15 15 15 16 16 16 16 20 20 20 ...
##  $ keyword    : Factor w/ 15 levels "BI","EXCEL","HADOOP",..: 2 9 15 2 15 3 10 15 10 11 ...
#提取非技能型关键词
keys <- worker(type = "keywords",user = "user_dict.txt",topn = 20,stop_word = "stopkw.txt")
keyword.lis <- lapply(CN.clean$description, function(x){
  v <- gsub("[a-zA-Z|0-9|\\.|\\-]","",keywords(x,keys))
  v <- v[v!=""]
  return(v)
})
keyword.lis <- unlist(keyword.lis)
#形成词频表
not.tool.keyword <- top.freq(keyword.lis)
str(not.tool.keyword)
## 'data.frame':    1497 obs. of  2 variables:
##  $ x   : Factor w/ 1497 levels "阿里","爱奇艺",..: 1243 990 1349 543 96 1298 742 439 1085 1097 ...
##  $ freq: int  236 157 132 119 110 108 87 85 82 76 ...

数据分析

library(ggplot2)
library(plyr)
library(wordcloud2)
attach(CN.clean)
## The following object is masked _by_ .GlobalEnv:
## 
##     id
source("myfun.R")
#观察数据的总体描述统计信息
summary(CN.clean[c("city","phase","scale","education","experience","avg_salary")])
##       city            phase           scale     education    experience 
##  北京   :222   不需要融资:94   15-50人   : 15   大专: 33   1年以下: 34  
##  杭州   : 48   上市公司  :88   50-150人  : 36   本科:389   1-3年  :156  
##  上海   : 48   D轮及以上 :80   150-500人 :104   硕士: 20   3-5年  :206  
##  广州   : 38   C轮       :73   500-2000人:116              5-10年 : 46  
##  深圳   : 38   B轮       :49   2000人以上:171                           
##  长沙   : 11   A轮       :42                                            
##  (Other): 37   (Other)   :16                                            
##    avg_salary   
##  Min.   : 2.50  
##  1st Qu.:12.50  
##  Median :17.50  
##  Mean   :18.22  
##  3rd Qu.:22.50  
##  Max.   :75.00  
## 
#创建ggplot绘图对象
p.cn <- ggplot(CN.clean)+my.ggplot.theme()

#问题1:不同地区,数据分析岗位的需求分布以及对应的薪资分布
city.table <- data.frame(prop.table(table(reorder_size(city,TRUE))))
names(city.table)[1] <- "city"
p1 <- ggplot(city.table,aes(x=city,y=Freq)) + my.ggplot.theme()+
  geom_bar(fill="turquoise3",stat = "identity") + 
  labs(x="城市",y="不同城市需求占总量的比率",
       title="“北京,上海,杭州,深圳,广州”占据了近90%的需求量,\n是数据分析师的首选") +
  scale_y_continuous(labels = scales::percent)

group_diff <- diff(range(avg_salary))/20
p2 <- p.cn + geom_histogram(aes(x=avg_salary,y=..density..),
                      binwidth = group_diff,fill="turquoise3",color="white")+
  stat_density(geom = "line",position = "identity",
               aes(x=avg_salary),color="brown1")+
  labs(x="月薪(K/月)",
       title="数据分析师平均月薪为18.22k,月薪的分布主要集中在10k~25k之间,\n拿到10k以上薪资的机会比较大") 

multiplot(p1,p2,cols = 1)

CN.clean$type <- NA
CN.clean$type[CN.clean$city %in% top.freq(city,5)$x] <- "top5"
CN.clean$type[is.na(CN.clean$type)] <- "other"
CN.clean$type <- factor(CN.clean$type,levels=c("top5","other"))
p.cn + geom_boxplot(aes(x=city,y=avg_salary,fill=CN.clean$type))+
  labs(x="城市",y="月薪(K/月)",
       title="需求量最多的5个城市的平均薪资均处于全国较高的水平,\n(苏州是一个特例,需求量少,薪资高)",fill="需求量排名")+
  theme(axis.text.x = element_text(angle = 30,hjust = 1))

#问题2:不同经验,数据分析岗位的需求分布以及对应的薪资分布
exp.table <- prop.table(table(experience))
exp.table <- as.data.frame(exp.table)
p3 <- ggplot(exp.table,aes(x=experience,y=Freq)) + my.ggplot.theme()+
  geom_bar(fill="turquoise3",stat = "identity") + 
  labs(x="工作经验",y="不同工作经验需求占总量的比率",
       title="企业需要更有经验的分析师,主要需求\n集中在1-3年和3-5年经验") +
  scale_y_continuous(labels = scales::percent)

p4 <- p.cn + geom_boxplot(aes(x=experience,y=avg_salary),fill="turquoise3")+
  labs(x="工作经验",y="平均月薪(K/月)",
       title="随着工作经验的增加,数据分析师的\n月薪有非常可观的增长")

multiplot(p3,p4,cols = 2)

#问题3:不同学历,数据分析岗位的需求分布以及对应的薪资分布

edu.table <- prop.table(table(education))
edu.table <- as.data.frame(edu.table)
p5 <- ggplot(edu.table,aes(x=education,y=Freq)) + my.ggplot.theme()+
  geom_bar(fill="turquoise3",stat = "identity") + 
  labs(x="学历",y="不同学历需求占总量的比率",title="超过90%的岗位需要本科及以上的学历") +
  scale_y_continuous(labels = scales::percent)
p6 <- p.cn + geom_boxplot(aes(x=education,y=avg_salary),fill="turquoise3")+
  labs(x="学历",y="月薪(K/月)",
       title="学历与薪资水平增长的关系不明显")
multiplot(p5,p6,cols = 2)

#问题4:不同企业规模,数据分析岗位的各项需求分布及薪资分布

scale.table <- data.frame(prop.table(table(scale)))
p7 <- ggplot(scale.table,aes(x=scale,y=Freq)) + my.ggplot.theme()+
  geom_bar(fill="turquoise3",stat = "identity") + 
  labs(x="企业规模",y="不同企业规模需求占总量的比率",title="接近90%的需求量集中在150人以上\n规模的企业")+
  theme(axis.text.x = element_text(angle = 30,hjust = 1))+
  scale_y_continuous(labels = scales::percent)
p8 <- p.cn + geom_boxplot(aes(x=scale,y=avg_salary),fill="turquoise3")+
  labs(x="企业规模",y="月薪(K/月)",
       title="150人以下规模且需快速发展的企业\n愿意给出更高的薪酬")+
  theme(axis.text.x = element_text(angle = 30,hjust = 1))
multiplot(p7,p8,cols = 2)

#企业规模与工作经验要求分析
sc.exp <- data.frame(prop.table(table(scale,experience),1))
ggplot(data=sc.exp,aes(x=scale,y=Freq,fill=experience)) + my.ggplot.theme()+
  geom_bar(stat = "identity")+
  labs(x="企业规模",y="需求比例",fill="工作经验",
       title="50~150人规模的企业对分析师的工作经验要求最高")+
  geom_text(aes(label=paste(round(sc.exp$Freq,3)*100,'%',sep = '')),colour = "white",
                   position=position_stack(.5), vjust=00)+
  scale_y_continuous(labels = scales::percent)

#问题5:探索数据分析岗位对工具型技能的需求

#工具型技能分布
key.df <- data.frame(table(reorder_size(merge.df$keyword,TRUE)))
key.df$Freq <- key.df$Freq/length(CN.clean$id)
ggplot(key.df)+my.ggplot.theme() + 
  geom_bar(aes(x=Var1,y=Freq),fill = "turquoise3",stat = "identity") + 
  labs(x="工具型技能",y="不同技能需求占总岗位需求量的比率",
       title="SQL,R,Python,Excel是数据分析师的必备技能,超过78%的岗位都要求掌握SQL,
       \nR语言的需求量居于第二") +
  theme(axis.text.x = element_text(angle = 30,hjust = 1))+
  geom_text(aes(x=Var1,y=Freq,label=paste(round(key.df$Freq,3)*100,'%',sep = '')),vjust=-0.2)+
  scale_y_continuous(labels = scales::percent)

#工具型技能与工作经验的分析
key.exp <- data.frame(prop.table(table(merge.df$keyword,merge.df$experience),2))
names(key.exp)[1:2] <- c("kw","exp")
ggplot(key.exp)+my.ggplot.theme()+
  geom_bar(aes(x=kw,y=Freq,fill=exp),stat = "identity")+
  labs(x="工具型技能",y="比率",fill="工作经验",
       title="工作经验要求越高对BI、EXCEL等office工具的需求越少,
       \n对数据库、Hadoop和Hive等大数据工具的需求越高")+
  facet_grid(exp~.)+
  theme(axis.text.x = element_text(angle = 30,hjust = 1))+
  geom_text(aes(x=kw,y=Freq,label=paste(round(key.exp$Freq,3)*100,'%',sep = '')),vjust=0,size=3)+
  scale_y_continuous(labels = scales::percent)

#工具型技能与薪资的分析
merge.df$type <- NA
merge.df$type[merge.df$keyword %in% top.freq(merge.df$keyword,5)$x] <- "top5"
merge.df$type[is.na(merge.df$type)] <- "other"
merge.df$type <- factor(merge.df$type,levels=c("top5","other"))
ggplot(merge.df) + my.ggplot.theme()+
  geom_boxplot(aes(x=keyword,y=avg_salary,fill=merge.df$type))+
  labs(x="工具型技能",y="月薪分布(K/月)",
       title="掌握Spark,Hadoop,Hive,R,Python等工具可以获得更高的薪资",fill="需求量排名")+
  theme(axis.text.x = element_text(angle = 30,hjust = 1))

#问题6:探索非工具型关键词的需求

#生成词云
wordcloud2(not.tool.keyword, size = 0.9, fontFamily = "微软雅黑")
detach(CN.clean)

总结

  1. 从地域来看,北京、深圳、上海、杭州、广州应该是数据分析师的首选城市,苏州是一个值得关注的城市,数据显示该苏州的GDP仅次于一线城市,平均薪资接近北京和深圳,但需求量较低,想要苏州发展的朋友可以关注其动态。
  2. 从总体需求来看,企业更加需要具备多年工作经验,且动手能力强、解决实际问题的分析人才,随着工作经验的增加,其对应的薪资也有可观的增长。
  3. 从大环境看,自助式分析工具的逐步完善与人工智能技术的突破,也可能使得企业现有业务人员能够上手基础的分析工作,导致企业对经验较低的分析师需求减少。
  4. 从企业规模看,150人以上规模的企业更加适合新人进去锻炼,一方面企业已经完成了基本的数据体系架构,且越大的企业数据量级越大,另一方面,企业需要逐步培养强大的数据分析团队来支撑业务的增长。
  5. 从分析师个人的角度,则需要更加关注自身成功项目经验的积累,这是升职加薪的必备条件,且需要思考未来自身的发展路径,提前做好准备,相对于业务方向,大数据工程师方向会有更可观的薪资。
  6. 从能力的角度,数据分析师需要掌握SQL,Excel,R,Python四个必备的工具(R和Python可以选择其一为主要工具),新人可以注重BI,PPT等office工具的技能,如果是大数据挖掘,越往后则需要更加关注hadoop,Hive,Spark等工具;
  7. 数据分析师个人还需要注重逻辑思维、表达沟通、分析报告等关键能力

建议

  1. 对于想要转型的数据分析师新人,转型之前尽可能做好项目经验的积累,尽量做到跨岗不跨行,在自己熟悉的领域学习数据分析
  2. 企业比较看重经验和动手能力,面试的时候尽可能展示你的作品或者案例,如果当前没有,则需要在日常学习,练习,积累
  3. 可以掌握一些可视化工具和数据可视化的思维,熟练掌握报告和表达的技巧,数据分析的工具多样,方式多样,只有能够正确解读数据且让对方看懂听懂才是有价值的

不足

本次分析并没有按照分析报告的方式来呈现,文章中以个人的整个分析过程来撰写,希望能够与各位朋友一起交流学习,如果你不同意我文章中的观点,欢迎指正交流。

文章中我附上了我的数据集以及分析的代码链接,有兴趣的朋友可以重复我的过程,甚至做更加深入有趣的分析,如果有新的发现和观点,希望也能让我知道,向你们学习。

附件

代码中还有部分函数是本人自己写的,存储在myfun.R文件中,代码如下:

#自定义ggplot2主题函数
my.ggplot.theme <- function(..., bg='white'){
  require(grid)
  theme_classic(...) +
    theme(rect=element_rect(fill=bg),
          plot.title = element_text(hjust = 0.5),
          text = element_text(family="STHeiti"),
          panel.background=element_rect(fill='transparent', color='#333333'),
          axis.line = element_line(colour = "#333333",size = 0.25),
          legend.key=element_rect(fill='transparent', color='transparent'),
          panel.border=element_rect(fill='transparent', color='transparent'),
          panel.grid=element_line(colour = 'grey95'),
          panel.grid.major = element_line(colour = "grey92",size = 0.25), 
          panel.grid.minor = element_line(colour = "grey92",size = 0.1))
}
#构建排序函数
reorder_size <- function(x,decreasing=TRUE) {
    factor(x, levels = names(sort(table(x),decreasing = decreasing)))
}
#返回一个频数表的数据框
top.freq <- function(x,topn=0){
  require(plyr)
  top.df <- count(x) 
  top.df <- top.df[order(top.df$freq,decreasing = TRUE),]
  if(topn > 0) return(top.df[1:topn,])
  else  return(top.df)
}
#ggplot2 多图显示函数
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  library(grid)
  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)
  numPlots = length(plots)
  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel
    # ncol: Number of columns of plots
    # nrow: Number of rows needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                     ncol = cols, nrow = ceiling(numPlots/cols))
  }
  if (numPlots==1) {
    print(plots[[1]])
  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                      layout.pos.col = matchidx$col))
    }
  }
}