教学目标

1.安装配置R语言环境 2.了解R Studio的界面和基本操作 3.学习变量、向量、数据框的使用方法 4.初步进行描述性统计的频次和统计量计算、信度计算、箱线图查看分析等操作

R软件安装

  1. R软件安装:https://cran.rstudio.com/
  2. R Studio安装:https://www.rstudio.com/products/rstudio/download/

参考书籍

  1. Andy Field, Jeremy Miles, Zoë Field - Discovering Statistics Using R
  2. J.D.隆 保罗·蒂特 - R语言经典实例(原书第2版)
  3. 卡巴科弗 - R语言实战(第2版) # R基本操作

注意:

1.一个#表示此行代码不运行,即注释

2.()和”“都要使用英文,如果中文会报错

新变量赋值

#<-表示等号=
x<-2
y<-4
z<-sqrt(x^2+y^2)
#输入某个变量,即可输出其内容
z
## [1] 4.472136

向量vector(一维数据)

数字类型

# 相同数字类型的向量
fib<-c(1,1,2,3,5,8,13,21)
fib
## [1]  1  1  2  3  5  8 13 21

文本类型

# 相同文本类型的向量
mon_list<-c('Jan','Feb','Mar','Apr')
mon_list
## [1] "Jan" "Feb" "Mar" "Apr"

函数使用

# 函数名称(函数应用的对象)
# 求均值
mean(fib)
## [1] 6.75
# 求中位数
median(fib)
## [1] 4
#求标准差
sd(fib)
## [1] 7.066015
#求方差
var(fib)
## [1] 49.92857

函数使用时缺失值的处理

f<-c(1,1,3,4,NA,7)
f
## [1]  1  1  3  4 NA  7
mean(f)
## [1] NA
# 添加na.rm = TRUE移除缺失值,用剩余元素计算
mean(f,na.rm=TRUE)
## [1] 3.2

生成有规律的序列向量

#n:m表示从n到m的整数
1:4
## [1] 1 2 3 4
5:-1
## [1]  5  4  3  2  1  0 -1
#seq(from = n, to = m, by = k) 表示从n到m每隔k生成序列
seq(from=1, to=10,by=2)
## [1] 1 3 5 7 9
seq(from=1, to=2,by=0.2)
## [1] 1.0 1.2 1.4 1.6 1.8 2.0
#rep(n,times=k)表示生成k个n
rep(2,times=10)
##  [1] 2 2 2 2 2 2 2 2 2 2

向量元素的获取

fib
## [1]  1  1  2  3  5  8 13 21
# 获取fib第1个元素
fib[1]
## [1] 1
# 获取第1-3个元素
fib[1:3]
## [1] 1 1 2
# 获取第1-3、5、7-9个元素,如果没有,则输出NA
fib[c(1:3,5,7:9)]
## [1]  1  1  2  5 13 21 NA
# 获取排除某个元素后的向量元素
fib[-4]
## [1]  1  1  2  5  8 13 21
# 获取特定值的元素,如小于于10
fib[fib<10]
## [1] 1 1 2 3 5 8
#如大于中位数
fib[fib>median(fib)]
## [1]  5  8 13 21

向量的运算

v <- c(3,pi,4)
w<- c(pi,pi,pi)
# 向量与向量比较/运算时,对应元素类型和个数相同,对应元素进行比较,并返回相应结果
# 返回布尔值c(3<pi,pi=pi,4>pi)
v>w
## [1] FALSE FALSE  TRUE
# 返回对应序列运算结果c(3+pi,pi+pi,4+pi)
v+w
## [1] 6.141593 6.283185 7.141593
v*w
## [1]  9.424778  9.869604 12.566371
# ==判断是否相等,! = 判断是否不等于
v==pi
## [1] FALSE  TRUE FALSE
v!=pi
## [1]  TRUE FALSE  TRUE
# 向量与标量比较/运算时,向量内元素逐一与标量比较,并返回布尔值
v[v>pi]
## [1] 4

数据框data.frame(二维数据)

导入spss或其他数据

# 直接file-》import dataset,选择文件即可
library(haven)
# 导入数据默认为数据框格式(data.frame)
eee_data <- read_sav("https://gitee.com/vv_victorwei/r-language-data-analysis/raw/master/Untitled2.sav")
# head会呈现eee_data的前六行数据,以预览概况
head(eee_data)
## # A tibble: 6 × 55
##   V1    time_used IP      id    gender   age birth…¹ roman…² hukou  hair homet…³
##   <chr>     <dbl> <chr>   <chr>  <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>   <dbl>
## 1 175         594 223.66… 2225…      1    23       1       0     0     1       0
## 2 124         178 101.88… 2222…      1    23       1       0     0     1       0
## 3 138         207 211.16… 2225…      1    22       0       0     1     1       0
## 4 74          176 58.246… 2122…      1    23       1       0     1     1       0
## 5 149         232 120.25… 2222…      1    22       0       0     0     1       0
## 6 11          142 58.40.… 1601…      1    23       1       0     1     1       0
## # … with 44 more variables: family_income <dbl>, minzhu <dbl>, zhiyuan <dbl>,
## #   height <dbl>, weight <dbl>, zhengzhi <dbl>, personality <dbl>, a1 <dbl>,
## #   a2 <dbl>, a3 <dbl>, a4 <dbl>, a5 <dbl>, a6 <dbl>, a7 <dbl>, a8 <dbl>,
## #   a9 <dbl>, a10 <dbl>, a11 <dbl>, a12 <dbl>, a13 <dbl>, b1 <dbl>, b2 <dbl>,
## #   b3 <dbl>, b4 <dbl>, b5 <dbl>, b6 <dbl>, importance_ranking <chr>,
## #   importance_ranking_d <dbl>, daode <dbl>, zhishi <dbl>, jineng <dbl>,
## #   yishu <dbl>, food <chr>, chuan_food <dbl>, yue_food <dbl>, …

查看数据框的列数据

#不同方法,第一种较简洁清晰,推荐
eee_data$gender
##   [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
##  [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1
##  [75] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
## [112] 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
## [149] 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0
## attr(,"format.spss")
## [1] "F3.0"
## attr(,"display_width")
## [1] 5
eee_data[,4]
## # A tibble: 175 × 1
##    id        
##    <chr>     
##  1 222503461 
##  2 222201390 
##  3 222503460 
##  4 212200325 
##  5 222201392 
##  6 160121468 
##  7 5649784366
##  8 212502294 
##  9 212502291 
## 10 212502261 
## # … with 165 more rows
eee_data[4]
## # A tibble: 175 × 1
##    id        
##    <chr>     
##  1 222503461 
##  2 222201390 
##  3 222503460 
##  4 212200325 
##  5 222201392 
##  6 160121468 
##  7 5649784366
##  8 212502294 
##  9 212502291 
## 10 212502261 
## # … with 165 more rows
eee_data['gender']
## # A tibble: 175 × 1
##    gender
##     <dbl>
##  1      1
##  2      1
##  3      1
##  4      1
##  5      1
##  6      1
##  7      1
##  8      1
##  9      1
## 10      1
## # … with 165 more rows
#调用多个变量的方法
eee_data[1:3]
## # A tibble: 175 × 3
##    V1    time_used IP                        
##    <chr>     <dbl> <chr>                     
##  1 175         594 223.66.32.30(江苏-常州)   
##  2 124         178 101.88.209.242(上海-上海) 
##  3 138         207 211.161.244.139(上海-上海)
##  4 74          176 58.246.234.173(上海-上海) 
##  5 149         232 120.253.249.229(上海-上海)
##  6 11          142 58.40.253.189(上海-上海)  
##  7 22          156 58.40.253.23(上海-上海)   
##  8 67          149 58.246.234.166(上海-上海) 
##  9 84          189 39.144.104.134(北京-北京) 
## 10 63          122 39.144.105.113(北京-北京) 
## # … with 165 more rows
eee_data[c(1,4,5:7)]
## # A tibble: 175 × 5
##    V1    id         gender   age birth_Jan_June
##    <chr> <chr>       <dbl> <dbl>          <dbl>
##  1 175   222503461       1    23              1
##  2 124   222201390       1    23              1
##  3 138   222503460       1    22              0
##  4 74    212200325       1    23              1
##  5 149   222201392       1    22              0
##  6 11    160121468       1    23              1
##  7 22    5649784366      1    23              1
##  8 67    212502294       1    23              1
##  9 84    212502291       1    22              0
## 10 63    212502261       1    22              1
## # … with 165 more rows
eee_data[c('age','height','weight')]
## # A tibble: 175 × 3
##      age height weight
##    <dbl>  <dbl>  <dbl>
##  1    23   1.62     44
##  2    23   1.67     63
##  3    22 164        68
##  4    23   1.68     49
##  5    22 168        60
##  6    23   1.66     53
##  7    23   1.56     50
##  8    23 161        50
##  9    22   1.51     62
## 10    22   1.58     48
## # … with 165 more rows

查看数据框的行数据

eee_data[1,]
## # A tibble: 1 × 55
##   V1    time_used IP      id    gender   age birth…¹ roman…² hukou  hair homet…³
##   <chr>     <dbl> <chr>   <chr>  <dbl> <dbl>   <dbl>   <dbl> <dbl> <dbl>   <dbl>
## 1 175         594 223.66… 2225…      1    23       1       0     0     1       0
## # … with 44 more variables: family_income <dbl>, minzhu <dbl>, zhiyuan <dbl>,
## #   height <dbl>, weight <dbl>, zhengzhi <dbl>, personality <dbl>, a1 <dbl>,
## #   a2 <dbl>, a3 <dbl>, a4 <dbl>, a5 <dbl>, a6 <dbl>, a7 <dbl>, a8 <dbl>,
## #   a9 <dbl>, a10 <dbl>, a11 <dbl>, a12 <dbl>, a13 <dbl>, b1 <dbl>, b2 <dbl>,
## #   b3 <dbl>, b4 <dbl>, b5 <dbl>, b6 <dbl>, importance_ranking <chr>,
## #   importance_ranking_d <dbl>, daode <dbl>, zhishi <dbl>, jineng <dbl>,
## #   yishu <dbl>, food <chr>, chuan_food <dbl>, yue_food <dbl>, …

查看数据框的指定单元格

eee_data$gender[3]
## [1] 1
# 行号在前,列号在后
eee_data[3,4]
## # A tibble: 1 × 1
##   id       
##   <chr>    
## 1 222503460

修改数据框中变量的名称

#将第1个变量的名字修改为global_id
names(eee_data)[1] <- "global_id"
head(eee_data[1])
## # A tibble: 6 × 1
##   global_id
##   <chr>    
## 1 175      
## 2 124      
## 3 138      
## 4 74       
## 5 149      
## 6 11
# 将a1~a13转化为zyrt_1~zyrt13
# 第一步,生成zyrt1~zyrt13的变量名,方法:将zyrt和1:13的序列通过_连接起来,代码:paste('zyrt',1:13,sep = "_")
# 第二步,找到a1~a13的列号19~31,重新命名
names(eee_data)[19:31]<-paste('zyrt',1:13,sep = "_")
head(eee_data[19:31])
## # A tibble: 6 × 13
##   zyrt_1 zyrt_2 zyrt_3 zyrt_4 zyrt_5 zyrt_6 zyrt_7 zyrt_8 zyrt_9 zyrt_10 zyrt_11
##    <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>   <dbl>   <dbl>
## 1      3      2      2      3      2      2      4      2      3       4       2
## 2      3      4      3      4      3      3      3      0      3       3       1
## 3      3      3      3      3      3      3      3      3      2       3       2
## 4      3      4      2      3      3      3      3      2      3       3       2
## 5      3      4      3      4      4      4      3      3      3       4       3
## 6      3      4      2      4      3      4      4      3      3       4       2
## # … with 2 more variables: zyrt_12 <dbl>, zyrt_13 <dbl>
#转换社交焦虑的变量名
names(eee_data)[32:37]<-paste('shjl',1:6,sep = "_")
head(eee_data[32:37])
## # A tibble: 6 × 6
##   shjl_1 shjl_2 shjl_3 shjl_4 shjl_5 shjl_6
##    <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
## 1      3      3      3      0      4      4
## 2      1      0      0      0      0      0
## 3      3      3      2      1      3      3
## 4      1      1      1      1      2      2
## 5      0      2      1      0      1      0
## 6      1      1      0      1      2      1

变量值的重新编码

(类似spss的recode into功能)

# 二分变量最简单:对于性别变量,0重新编码为男,1重新编码为女
eee_data$gender_text <- ifelse(eee_data$gender=="0","男","女")
head(eee_data$gender_text)
## [1] "女" "女" "女" "女" "女" "女"
# ifelse语句只能编码两个值的变量,多值变量的重新编码用到dplyr库
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
eee_data$zhiyuan_text <- recode(eee_data$zhiyuan, "1" = "第一志愿", "2" = "第二志愿","3"="第三志愿以及其他")
head(eee_data$zhiyuan_text)
## [1] "第三志愿以及其他" "第三志愿以及其他" "第一志愿"         "第二志愿"        
## [5] "第三志愿以及其他" "第三志愿以及其他"

描述性统计

频次统计

# 计算频次
table(eee_data$gender)
## 
##   0   1 
##   9 166
# 计算百分比
prop.table(table(eee_data$gender))
## 
##          0          1 
## 0.05142857 0.94857143
# 计算两个变量的交叉表
table(eee_data$birth_Jan_June,eee_data$roman_relations)
##    
##      0  1
##   0 39 29
##   1 63 44

统计量计算

# 调用psych的库
library(psych)
describe(eee_data$height)
##    vars   n  mean    sd median trimmed  mad  min max  range skew kurtosis   se
## X1    1 175 38.43 67.85   1.65   27.23 0.07 1.51 182 180.49 1.29    -0.33 5.13
describe(eee_data[c('age','height','weight')])
##        vars   n  mean    sd median trimmed  mad   min max  range skew kurtosis
## age       1 175 23.37  2.45  23.00   22.87 1.48 20.00  37  17.00 2.77     9.52
## height    2 175 38.43 67.85   1.65   27.23 0.07  1.51 182 180.49 1.29    -0.33
## weight    3 175 54.06  9.00  52.00   52.81 5.93 40.00  96  56.00 1.94     5.17
##          se
## age    0.19
## height 5.13
## weight 0.68
# 按照hometown分组计算
describeBy(eee_data[c('age','height','weight')],group=eee_data$hometown)
## 
##  Descriptive statistics by group 
## group: 0
##        vars   n  mean    sd median trimmed  mad   min max  range skew kurtosis
## age       1 103 23.26  2.22  23.00   22.82 1.48 20.00  35  15.00 2.45     7.67
## height    2 103 31.07 62.22   1.65   18.47 0.07  1.53 174 172.47 1.61     0.61
## weight    3 103 53.98  9.21  52.00   52.69 5.93 40.00  92  52.00 1.73     3.81
##          se
## age    0.22
## height 6.13
## weight 0.91
## ------------------------------------------------------------ 
## group: 1
##        vars  n  mean    sd median trimmed  mad   min max  range skew kurtosis
## age       1 72 23.51  2.76  23.00   22.95 1.48 21.00  37  16.00 2.85     9.19
## height    2 72 48.97 74.35   1.66   39.98 0.09  1.51 182 180.49 0.90    -1.19
## weight    3 72 54.18  8.75  52.00   53.02 4.45 40.00  96  56.00 2.25     7.24
##          se
## age    0.33
## height 8.76
## weight 1.03

箱线图

boxplot(eee_data$age)

问卷数据处理,计算信度

#使用psych处理量表数据的函数scoreItems
#首先得说明那几个变量是专业认同zyrt,哪几个是社会焦虑shjl,直接将变量名组合成一个向量,放在list里
#结果中第一个alpha就是Cronbach' alpha系数
questionnair.key<-list(
zyrt= c(paste('zyrt',1:13,sep='_')),
shjl=c(paste('shjl',1:6,sep='_')))
questionnair.scales<-scoreItems(questionnair.key,eee_data)
questionnair.scales
## Call: scoreItems(keys = questionnair.key, items = eee_data)
## 
## (Unstandardized) Alpha:
##       zyrt shjl
## alpha 0.85 0.84
## 
## Standard errors of unstandardized Alpha:
##        zyrt  shjl
## ASE   0.026 0.037
## 
## Average item correlation:
##           zyrt shjl
## average.r  0.3 0.47
## 
## Median item correlation:
## zyrt shjl 
## 0.28 0.50 
## 
##  Guttman 6* reliability: 
##          zyrt shjl
## Lambda.6 0.88 0.87
## 
## Signal/Noise based upon av.r : 
##              zyrt shjl
## Signal/Noise  5.5  5.3
## 
## Scale intercorrelations corrected for attenuation 
##  raw correlations below the diagonal, alpha on the diagonal 
##  corrected correlations above the diagonal:
##       zyrt  shjl
## zyrt  0.85 -0.20
## shjl -0.17  0.84
## 
##  Average adjusted correlations within and between scales (MIMS)
##      zyrt  shjl 
## zyrt  0.30      
## shjl -0.06  0.47
## 
##  Average adjusted item x scale correlations within and between scales (MIMT)
##      zyrt  shjl 
## zyrt  0.60      
## shjl -0.13  0.74
## 
##  In order to see the item by scale loadings and frequency counts of the data
##  print with the short option = FALSE

计算量表得分均值

# 对每一行,计算指定变量的均值。效果等同于spss的compute variable
eee_data$zyrt<-rowMeans(eee_data[19:31],na.rm = TRUE)
eee_data$shjl<-rowMeans(eee_data[32:37],na.rm = TRUE)
head(eee_data$zyrt)
## [1] 2.615385 2.692308 2.923077 2.846154 3.538462 3.384615
head(eee_data$shjl)
## [1] 2.8333333 0.1666667 2.5000000 1.3333333 0.6666667 1.0000000

其他高级操作

将数据库里面的变量名放进R分析环境中直接调用

  • 好处是节省了“数据框名称$”输入之苦
  • 坏处是分析文档中如果有两个变量或者对象名称相同,就可能会混淆导致错误
  • 个人建议慎用,在使用前要仔细检查是否有变量名重合
# gender是eee_data的一个变量名,但是不能直接通过代码调用
#试着输入gender,看下反应。
#会提示Error: object 'gender' not found

#可以把eee_data里面所有变量名放进分析环境中
attach(eee_data)
head(gender)
## [1] 1 1 1 1 1 1
#一般情况下,这样容易与其他变量的名称混淆,如果要解除这种操作
detach(eee_data)

#试着输入gender,看下反应。
#会提示Error: object 'gender' not found

循环语句

循环语句可以大大减少工作量,语句:for(i in 需要处理的对象集合){语句}

# 导入R时第19~37列变量都默认了文本型,但实际上是数字型,我们需要进行转化
# 将某个变量x转化为数字型的函数是as.numeric(x),但由于很多,可以利用循环
# i的含义是代替后面需要处理的集合中的任一对象
for (i in eee_data[19:37]){i = as.numeric(i)}
head(eee_data[19])
## # A tibble: 6 × 1
##   zyrt_1
##    <dbl>
## 1      3
## 2      3
## 3      3
## 4      3
## 5      3
## 6      3

条件语句

  1. 当条件应用的对象是向量时,语法格式:ifelse(条件,条件为真的结果,条件为假的结果)

  2. 当条件应用的对象是标量(一个值)时,语法格式if(条件){条件为真的结果}else{条件为假的结果}

# height有些人按照厘米为单位填写,因此会有100以上的结果
# 为了矫正该变量,需要使用条件语句,如果值大于100,则需要身高值*0.01,否则是身高值
# 由于对象是向量height,因此使用ifelse
head(eee_data$height)
## [1]   1.62   1.67 164.00   1.68 168.00   1.66
eee_data$height_corrected<-ifelse(eee_data$height>100,0.01*eee_data$height,eee_data$height)
head(eee_data$height_corrected)
## [1] 1.62 1.67 1.64 1.68 1.68 1.66
#也可以使用if 但由于对象是标量,可借助for语句
#从第1行到第175行进行循环,每行判断此行身高是否大于100,如果大于100,则纠正后的变量值乘以0.01,否则直接用原来的。
eee_data$height_corrected_f<-eee_data$height
for (i in 1:175)
{if(eee_data$height[i]>100){eee_data$height_corrected_f[i]<-0.01*eee_data$height[i]}else{eee_data$height_corrected_f[i]=eee_data$height[i]}}
head(eee_data$height_corrected_f)
## [1] 1.62 1.67 1.64 1.68 1.68 1.66