目录
一、读取和保存数据
1、读取外部数据
(1) 读取不含有标题的csv格式数据
(2) 读取含有标题的csv格式数据
(3)读取R格式数据
2、保存数据
(1)将数据保存成csv格式
(2)将数据保存成R格式
二、随机数和数据抽样
1、生成随机数
2、数据抽样
三、生成频数分布表
1、类别数据频数分布表
(1)一维列联表
(二)二维列联表
(三)多维列联表
2、数值数据类别化
(1)按组数分割
(2)按组距分割
(3)使用DescTools包中的Freq函数生成频数分布表
四、数据类型的转换
1、将变量转换为向量
2、将数据框转换成矩阵
3、将列联表转化成数据框
4、将短格式数据转化成长格式数据
(1)将短格式数据转化成长格式数据(数据框中有标识变量(类别因子))
(2)将短格式数据转化成长格式数据(数据框中无标识变量)
一、读取和保存数据
1、读取外部数据
(1) 读取不含有标题的csv格式数据
table1_1 <- read.csv('./mydata/chap01/table1_1.csv', header = FALSE)
head(table1_1)
V1 V2 V3
1 性别 网购次数 满意度
2 女 6次以上 满意
3 男 3~5次 不满意
4 女 3~5次 不满意
5 男 3~5次 中立
6 女 1~2次 满意
(2) 读取含有标题的csv格式数据
table1_1 <- read.csv('./mydata/chap01/table1_1.csv')
head(table1_1)
性别 网购次数 满意度
1 女 6次以上 满意
2 男 3~5次 不满意
3 女 3~5次 不满意
4 男 3~5次 中立
5 女 1~2次 满意
6 男 6次以上 不满意
(3)读取R格式数据
load('./mydata/chap01/table1_1.RData')
2、保存数据
(1)将数据保存成csv格式
write.csv(table1_1, file='./mydata/chap01/table1_1_1.csv')
(2)将数据保存成R格式
save(table1_1, file='./mydata/chap01/table1_1.RData')
二、随机数和数据抽样
1、生成随机数
# 生成不同分布的随机数
rnorm(10) # 产生10个标准正态分布随机数
rnorm(10, 50, 5) # 产生10个均值为50,标准差为5的正态分布随机数
runif(10, 0, 100) # 在0~100之间产生10个均匀分布随机数
rchisq(10, 15) # 产生10个自由度为1.5的卡方分布随机数
# 想产生相同的随机数,使用set.seed()设定种子,如set.seed(10)
2、数据抽样
n <- 1:10
n1 <- sample(n, size=8) # 无放回抽取10个数据
n1
[1] 9 7 8 6 3 2 10 5
n2 <- sample(n, size=8, replace=TRUE) # 有放回抽取10个数据
n2
[1] 2 8 8 7 6 7 6 2
三、生成频数分布表
频数分布表:对类别数据(因子的水平)计数或数值数据类别化(分组)后计数生成的表格。
1、类别数据频数分布表
(1)一维列联表
# 读入数据【2000个消费者的网购情况调查数据】
data1_1 <- read.csv('./mydata/chap01/data1_1.csv')
head(data1_1,5)
性别 网购次数 满意度
1 女 6次以上 满意
2 男 3~5次 不满意
3 女 3~5次 不满意
4 男 3~5次 中立
5 女 1~2次 满意
# 查看数据结构
str(data1_1)
'data.frame': 2000 obs. of 3 variables:
$ 性别 : chr "女" "男" "女" "男" ...
$ 网购次数: chr "6次以上" "3~5次" "3~5次" "3~5次" ...
$ 满意度 : chr "满意" "不满意" "不满意" "中立" ...
# 生成满意度的一维表
mytable1 <- table(data1_1$满意度)
mytable1
不满意 满意 中立
800 520 680
# 将mytable1转换为百分比表
prop.table(mytable1) * 100
不满意 满意 中立
40 26 34
(二)二维列联表
二维列联表:一个名称放在“行”位置,另一个变量各类别放在“列”位置
# 生成性别和满意度的二维列联表
mytable2 <- table(data1_1$性别, data1_1$满意度)
mytable2
不满意 满意 中立
男 360 160 320
女 440 360 360
prop.table(mytable2) # 所占总量的百分比
不满意 满意 中立
男 0.18 0.08 0.16
女 0.22 0.18 0.18
prop.table(mytable2, 1) # 行汇总的百分比
不满意 满意 中立
男 0.4285714 0.1904762 0.3809524
女 0.3793103 0.3103448 0.3103448
prop.table(mytable2, 2) # 列汇总的百分比
不满意 满意 中立
男 0.4500000 0.3076923 0.4705882
女 0.5500000 0.6923077 0.5294118
addmargins(mytable2) # 为列联表添加边际和
不满意 满意 中立 Sum
男 360 160 320 840
女 440 360 360 1160
Sum 800 520 680 2000
(三)多维列联表
多维列联表:将一个或多个变量按“列”摆放,其余变按“行”摆放。
# 生成三维列联表(列变量为“满意度”)
mytable3 <- ftable(data1_1, row.vars = c("性别", "网购次数"), col.vars = "满意度")
mytable3
满意度 不满意 满意 中立
性别 网购次数
男 1~2次 117 57 106
3~5次 137 54 131
6次以上 106 49 83
女 1~2次 122 114 102
3~5次 179 141 162
6次以上 139 105 96
# 生成三维列联表(列变量为"性别"和"满意度")
mytable4 <- ftable(data1_1, row.vars = '网购次数', col.vars = c('性别', '满意度'))
mytable4
性别 男 女
满意度 不满意 满意 中立 不满意 满意 中立
网购次数
1~2次 117 57 106 122 114 102
3~5次 137 54 131 179 141 162
6次以上 106 49 83 139 105 96
# 使用structable函数生成多维表
library(vcd)
structable(data1_1)
网购次数 1~2次 3~5次 6次以上
性别 满意度
男 不满意 117 137 106
满意 57 54 49
中立 106 131 83
女 不满意 122 179 139
满意 114 141 105
中立 102 162 96
structable(网购次数 ~性别 + 满意度, data1_1)
网购次数 1~2次 3~5次 6次以上
性别 满意度
男 不满意 117 137 106
满意 57 54 49
中立 106 131 83
女 不满意 122 179 139
满意 114 141 105
中立 102 162 96
2、数值数据类别化
# 读入数据【某购物网站60天的销售额】
data1_2 <- read.csv('./mydata/chap01/data1_2.csv')
# 查看数据前5行
head(data1_2, 5)
销售额
1 572
2 588
3 678
4 604
5 606
# 查看数据结构
str(data1_2)
'data.frame': 60 obs. of 1 variable:
$ 销售额: int 572 588 678 604 606 686 623 537 566 578 ...
# 查看销售额字段值类型
class(data1_2$销售额)
[1] "integer"
(1)按组数分割
注:生成数值数据频数分布表,先将其类别化(转化为类别或因子数据)
nclass.Sturges(data1_2$销售额) #nclass.Sturges可算出大概数,具体组数可根据需要调整
v <- as.vector(data1_2$销售额) # 将销售额转化为向量
cut(v, breaks = 7) # 按组数切割:将数值向量切割成7组
[1] (561,590] (561,590] (649,679] (590,620] (590,620] (679,708] (620,649] (531,561] (561,590] (561,590] (649,679]
[12] (590,620] (620,649] (590,620] (561,590] (679,708] (620,649] (502,531] (620,649] (561,590] (531,561] (561,590]
[23] (531,561] (561,590] (561,590] (502,531] (620,649] (590,620] (531,561] (649,679] (620,649] (561,590] (620,649]
[34] (620,649] (620,649] (620,649] (620,649] (590,620] (561,590] (561,590] (561,590] (561,590] (531,561] (679,708]
[45] (649,679] (531,561] (561,590] (561,590] (620,649] (590,620] (590,620] (590,620] (590,620] (649,679] (561,590]
[56] (649,679] (502,531] (620,649] (590,620] (590,620]
Levels: (502,531] (531,561] (561,590] (590,620] (620,649] (649,679] (679,708]
cut(v, breaks = 7, right = F) # 左闭右开
[1] [561,590) [561,590) [649,679) [590,620) [590,620) [679,708) [620,649) [531,561) [561,590) [561,590) [649,679)
[12] [590,620) [620,649) [590,620) [561,590) [679,708) [620,649) [502,531) [620,649) [561,590) [531,561) [561,590)
[23] [531,561) [561,590) [561,590) [502,531) [620,649) [590,620) [531,561) [649,679) [620,649) [561,590) [620,649)
[34] [620,649) [620,649) [620,649) [620,649) [590,620) [561,590) [561,590) [561,590) [561,590) [531,561) [679,708)
[45] [649,679) [531,561) [561,590) [561,590) [620,649) [590,620) [590,620) [590,620) [590,620) [649,679) [561,590)
[56] [649,679) [502,531) [620,649) [590,620) [590,620)
Levels: [502,531) [531,561) [561,590) [590,620) [620,649) [649,679) [679,708)
data1_2$销售额类别 = cut(v, breaks = 5)
head(data1_2,5)
销售额 销售额类别
1 572 (543,584]
2 588 (584,626]
3 678 (667,708]
4 604 (584,626]
5 606 (584,626]
(2)按组距分割
# 组距=(最大值 - 最小值)/组数
(max(v) - min(v))/5
mi <- floor(min(v) / 41)
ma <- ceiling(max(v) / 41)
cut(v, breaks = 41*(mi:ma)) # 按组距切割:将数值向量切割成组距为41
[1] (533,574] (574,615] (656,697] (574,615] (574,615] (656,697] (615,656] (533,574] (533,574] (574,615] (656,697]
[12] (615,656] (615,656] (574,615] (533,574] (656,697] (615,656] (492,533] (615,656] (574,615] (533,574] (574,615]
[23] (533,574] (533,574] (533,574] (492,533] (615,656] (574,615] (533,574] (656,697] (615,656] (574,615] (615,656]
[34] (615,656] (615,656] (615,656] (615,656] (574,615] (574,615] (574,615] (533,574] (574,615] (533,574] (697,738]
[45] (656,697] (533,574] (574,615] (574,615] (615,656] (574,615] (574,615] (574,615] (574,615] (656,697] (574,615]
[56] (656,697] (492,533] (615,656] (574,615] (574,615]
Levels: (492,533] (533,574] (574,615] (615,656] (656,697] (697,738]
# 确定组数的常用方法
nclass.Sturges(v)
# 确定组距的方法:组距 = (最大值 - 最小值) / 组数
(max(v) - min(v)) / nclass.Sturges(v)
注:组数和组距可根据分析需要调整
# 分成间隔为30的组,右开
d <- table(cut(v, breaks = 30*(16:24), right = F))
dd <- data.frame(d) # 组织成数据框
dd
Var1 Freq
1 [480,510) 1
2 [510,540) 4
3 [540,570) 8
4 [570,600) 17
5 [600,630) 14
6 [630,660) 7
7 [660,690) 8
8 [690,720) 1
# 计算频数百分比,结果 保留2位小数
percent <- round(dd$Freq/sum(dd$Freq) * 100, 2)
df <- data.frame(dd, percent) # 组织成数据框
df
Var1 Freq percent
1 [480,510) 1 1.67
2 [510,540) 4 6.67
3 [540,570) 8 13.33
4 [570,600) 17 28.33
5 [600,630) 14 23.33
6 [630,660) 7 11.67
7 [660,690) 8 13.33
8 [690,720) 1 1.67
# 重新命名并组织成频数分布表
mytable <- data.frame(分组 = df$Var1, 频数 = df$Freq, 频数百分比 = df$percent)
mytable
分组 频数 频数百分比
1 [480,510) 1 1.67
2 [510,540) 4 6.67
3 [540,570) 8 13.33
4 [570,600) 17 28.33
5 [600,630) 14 23.33
6 [630,660) 7 11.67
7 [660,690) 8 13.33
8 [690,720) 1 1.67
# 实际分组时,可将组距确定易于理解的值,如50
# 分组间隔为50,并生成频数分布表
d <- table(cut(v, breaks = c(500, 550, 600, 650, 700, 750), right = F))
d
[500,550) [550,600) [600,650) [650,700) [700,750)
9 21 21 8 1
(3)使用DescTools包中的Freq函数生成频数分布表
data1_2 <- read.csv('./mydata/chap01/data1_2.csv')
# install.packages('DescTools')
library(DescTools)
# A.默认分组,含上限值
# 简单代码得到组别(level)、各组的频数(freq)、各组频数百分比(perc)、累积频数(cumfreq)、累积频数百分比(cumprec
tab <- Freq(data1_2$销售额)
tab
level freq perc cumfreq cumperc
1 [500,550] 9 15.0% 9 15.0%
2 (550,600] 21 35.0% 30 50.0%
3 (600,650] 21 35.0% 51 85.0%
4 (650,700] 8 13.3% 59 98.3%
5 (700,750] 1 1.7% 60 100.0%
# B.使用Freq函数生成频数分布表,指定组距=20
20*(25:36)
tab1 <- Freq(data1_2$销售额, breaks = 20*(25:36), right = F)
tab1
tab2 <- data.frame(分组 = tab1$level,
频数 = tab1$freq,
频数百分比 = tab1$perc * 100,
累积频数 = tab1$cumfreq,
累积百分比 = tab1$cumperc * 100)
print(tab2, digits = 3) # 用print函数定义输出结果的小数位数
分组 频数 频数百分比 累积频数 累积百分比
1 [500,520) 2 3.33 2 3.33
2 [520,540) 3 5.00 5 8.33
3 [540,560) 4 6.67 9 15.00
4 [560,580) 9 15.00 18 30.00
5 [580,600) 12 20.00 30 50.00
6 [600,620) 8 13.33 38 63.33
7 [620,640) 9 15.00 47 78.33
8 [640,660) 4 6.67 51 85.00
9 [660,680) 6 10.00 57 95.00
10 [680,700) 2 3.33 59 98.33
11 [700,720] 1 1.67 60 100.00
四、数据类型的转换
1、将变量转换为向量
table1_1 <- read.csv('./mydata/chap01/table1_1.csv')
table1_1
姓名 统计学 数学 经济学
1 刘文涛 68 85 84
2 王宇翔 85 91 63
3 田思雨 74 74 61
4 徐丽娜 88 100 49
5 丁文彬 63 82 89
vector1 <- as.vector(table1_1$统计学) # 将统计学分数转换成向量
# 将统计学和数学分数合并转换成一个向量
vector2 <- as.vector(c(table1_1$统计学, table1_1$数学))
vector1;vector2
[1] 68 85 74 88 63
[1] 68 85 74 88 63 85 91 74 100 82
2、将数据框转换成矩阵
# 将table1_1中的第2~4列转换成矩阵mat
mat <- as.matrix(table1_1[, 2:4])
mat
# 矩阵的行名为table1_1第1列的名称
rownames(mat) = table1_1[, 1]
mat
统计学 数学 经济学
刘文涛 68 85 84
王宇翔 85 91 63
田思雨 74 74 61
徐丽娜 88 100 49
丁文彬 63 82 89
# 将矩阵转换成数据框
as.data.frame(mat)
3、将列联表转化成数据框
library(DescTools)
# 将列联表转化成数据框
df <- Untable(mytable3)
head(df, 3) #后三行tail(df, 3)
性别 网购次数 满意度
1 男 1~2次 不满意
2 男 1~2次 不满意
3 男 1~2次 不满意
# 将列联表转化成带有类别频数的数据框
data1_1 <- read.csv('./mydata/chap01/data1_1.csv')
tab <- ftable(data1_1) # 生成列联表(也可以使用table函数生成列联表)
df <- as.data.frame(tab) # 将列联表转化成带有类别频数的数据框
head(df)
性别 网购次数 满意度 Freq
1 男 1~2次 不满意 117
2 女 1~2次 不满意 122
3 男 3~5次 不满意 137
4 女 3~5次 不满意 179
5 男 6次以上 不满意 106
6 女 6次以上 不满意 139
reshape2::melt(table(data1_1)) # 与ftable(data1_1)效果相同
性别 网购次数 满意度 value
1 男 1~2次 不满意 117
2 女 1~2次 不满意 122
3 男 3~5次 不满意 137
4 女 3~5次 不满意 179
5 男 6次以上 不满意 106
6 女 6次以上 不满意 139
7 男 1~2次 满意 57
8 女 1~2次 满意 114
9 男 3~5次 满意 54
10 女 3~5次 满意 141
11 男 6次以上 满意 49
12 女 6次以上 满意 105
13 男 1~2次 中立 106
14 女 1~2次 中立 102
15 男 3~5次 中立 131
16 女 3~5次 中立 162
17 男 6次以上 中立 83
18 女 6次以上 中立 96
4、将短格式数据转化成长格式数据
(1)将短格式数据转化成长格式数据(数据框中有标识变量(类别因子))
table1_1
姓名 统计学 数学 经济学
1 刘文涛 68 85 84
2 王宇翔 85 91 63
3 田思雨 74 74 61
4 徐丽娜 88 100 49
5 丁文彬 63 82 89
library(reshape2)
melt(table1_1, id.vars = '姓名') # 保持'姓名'列固定,其它列会自动融合
# variable.name、value.name分别用来设定列变量和值的名称
tab_long <- melt(table1_1, id.vars = '姓名', variable.name = '课程', value.name = '分数')
tab_long
姓名 课程 分数
1 刘文涛 统计学 68
2 王宇翔 统计学 85
3 田思雨 统计学 74
4 徐丽娜 统计学 88
5 丁文彬 统计学 63
6 刘文涛 数学 85
7 王宇翔 数学 91
8 田思雨 数学 74
9 徐丽娜 数学 100
10 丁文彬 数学 82
11 刘文涛 经济学 84
12 王宇翔 经济学 63
13 田思雨 经济学 61
14 徐丽娜 经济学 49
15 丁文彬 经济学 89
(2)将短格式数据转化成长格式数据(数据框中无标识变量)
table1_4 <- read.csv('./mydata/chap01/table1_4.csv')
table1_4
统计学 数学 经济学
1 68 85 84
2 85 91 63
3 74 74 61
4 88 100 49
5 63 82 89
tab_long <- melt(table1_4, variable.name = '课程', value.name = '分数') # 不使用标识变量直接融合
tab_long
课程 分数
1 统计学 68
2 统计学 85
3 统计学 74
4 统计学 88
5 统计学 63
6 数学 85
7 数学 91
8 数学 74
9 数学 100
10 数学 82
11 经济学 84
12 经济学 63
13 经济学 61
14 经济学 49
15 经济学 89
使用tidyr包中的gather函数融合数据
library(tidyr)
# key、value分别用来设定列变量和值的名称
df1 <- gather(table1_1, key = '课程', value = '分数', '统计学', '数学', '经济学')
df1