一、查看和编辑数据
1、查看数据
直接打印到控制台
x <- data.frame(a=1:20, b=21:30)
x
View()函数
此函数可以将数据以电子表格的形式进行展示。
用reshape2包中的tips进行举例:
library("reshape2")
View(tips)
head()函数
查看前几行数据,参数n表示需要查看的行数,默认为6
tail()函数
查看后几行数据,参数n表示需要查看的行数,默认为6
2、编辑数据
fix()函数
数据较少时,可以用此函数来编辑数据。使用时,会出现如下所示的一个弹窗,可以直接在这上面编辑数据。
当数据量特别大时,不适宜用此方法。
fix(tips)
edit()函数
使用此函数,会生成一个新的数据,如果没有将新数据赋值给变量,它将直接打印到控制台。使用时,也会出现如下所示的一个弹窗,可以直接在这上面编辑数据。
当数据量特别大时,不适宜用此方法。
edit(tips)
二、筛选数据
subset()函数
此函数可对向量、矩阵和数据框提取子集,它允许直接使用列名或变量名,使得相较于中括号来说可读性更强。
以下通过reshape2包中的tips数据集进行举例:
# 筛选tips数据集中,星期天消费大于40美元,小费大于5美元,且不吸烟的男性买单
# 方法一:用中括号
tips[tips$total_bill > 20 &
tips$tip > 5 &
tips$sex == "Male" &
tips$smoker == "No" &
tips$day == "Sun",
c("total_bill", "tip", "sex", "smoker", "day")]
# 方法二:使用subset()函数进行筛选
subset(tips,
subset = total_bill > 20 &
tip > 5 &
sex == "Male" &
smoker == "No" &
day == "Sun",
select = c("total_bill", "tip", "sex", "smoker", "day")
)
将上述方法一进行改进:使用with()函数,它的作用是对当前数据构建一个环境,并在该环境中计算表达式。
with(tips,
tips[total_bill > 20 &
tip > 5 &
sex == "Male" &
smoker == "No" &
day == "Sun",
c("total_bill", "tip", "sex", "smoker", "day")])
sample()函数:随机抽样
此函数的3个重要参数:
- size:抽样数量
- replace:是否有放回地抽样
- prob:按照一定的概率进行抽样
x <- letters
sample(x, size=12)
y <- array(LETTERS[1:24], dim=c(3,4,2))
sample(y,size=12)
如果对数据框和列表使用sample()函数,那么得到的结果是对列或元素的随机抽样。对数据框来说,希望得到对行的随机抽样,所以需要先对行号随机抽样,然后选取相应的行。
对列表进行随机抽样:
x <- list(a = c(1,3,4), b = letters, c=3:15, d=month.abb)
x
sample(x, size=3)
对数据框进行随机抽样:
tips[sample(1:nrow(tips), 3),]
三、合并数据
paste()和paste0()函数
将向量以字符串的形式拼接起来。
c()函数
将几个向量合并为更大的向量或列表
data.frame()函数
合并数据框。
cbind()函数
按列合并
x <- tips[,c(1,2)]
head(x)
y <- tips[,c(5,6)]
head(y)
z <- cbind(x,y)
head(z)
rbind()函数
按行合并,且在合并时数据的列名称必须一样,但对列的顺序没要求。
x <- tips[sample(1:nrow(tips), 100),]
head(x)
y <- tips[sample(1:nrow(tips), 50),][,7:1] # y的列名称顺序与x相反
head(y)
z <- rbind(x,y)
head(z)
merge()函数
# 构建作者信息表
authors <- data.frame(
name = I(c("Tukey", "Venables", "Tierney", "Ripley", "McNeil")),
nationality = c("US", "Australia", "US", "UK", "Australia"),
deceased = c("yes", rep("no", 4)))
authors
authors.new <- within(authors,
{ surname <- name; rm(name) })
authors.new
# 构建著作信息表
books <- data.frame(
name = I(c("Tukey", "Venables", "Tierney",
"Ripley", "Ripley", "McNeil", "R Core")),
other.author = c(NA, "Ripley", NA, NA, NA, NA,"Venables & Smith"),
title = c("Exploratory Data Analysis",
"Modern Applied Statistics with S-PLUS",
"LISP-STAT",
"Spatial Statistics",
"Stochastic Simulation",
"Interactive Data Analysis",
"An Introduction to R"),
publishers = c("Addison-Wesley","Springer","Wiley-Interscience",
"Springer","Wiley-Interscience",
"Wiley","Samurai Media Limited"),
year = c(1977,1994,1990,1988,2006,1992,2015))
books
合并有相同列名的数据框
merge(authors,books,by = "name")
合并没有相同列名的数据框
merge(authors.new,books,by.x = "surname",by.y = "name")
四、分组和汇总
cut()函数
x <- rnorm(20,10,5)
# 按c(min(x),5,10,15,max(x))区间将x分成4个区间(组)
# include.lowest表示第一组是否包含最小值
cut(x,breaks = c(min(x),5,10,15,max(x)),include.lowest = T)
# 可以为每一个组赋予标签
cut(x,breaks = c(min(x),5,10,15,max(x)),
labels = c("第一组","第二组","第三组","第四组"),
include.lowest = T)
# 实际应用中往往是在数据框中生成新列
a <- data.frame(x = x)
a$y <- cut(a$x,breaks = c(min(a$x),5,10,15,max(a$x)),
labels = c("第一组","第二组","第三组","第四组"),
include.lowest = T)
head(a)
split()函数
通过分组变量以列表的形式将向量或者数据框分割为若干组。
b <- split(a$x,a$y)
str(b)
unsplit()函数
将分组结果还原。
c <- unsplit(b,a$y)
c
rowsum()函数
分组求和。
rowsum(a$x,group = a$y)
table()与xtabs()函数
计算每一组的元素数量。
table(a$x)
xtabs(~ x, a)
aggregate()函数
用于数据汇总。
library(reshape2)
# 按sex、smoker计算tips数据集中tatal_bill和tip的平均值
aggregate(tips[,c("total_bill","tip")],list(tips$sex,tips$smoker),mean)
aggregate(cbind(total_bill,tip) ~ sex + smoker,data = tips,mean)
五、排序数据
sort()函数
常用于对数值向量或因子就行排序。
如果向量中有NA,sort()函数会自动舍弃掉,如果想要保留,可通过na.last参数控制。
sort()函数默认以升序排序,可通过设置decreasing参数为TRUE,使其按照降序排序。
x <- c(1,4,3,7,8,9,1,NA)
sort(x)
sort(x, na.last=T, decreasing=T)
y <- factor(rep(c("东","西","北","南"),3), levels = c("东","南","西","北"))
sort(y)
rank()函数
此函数的操作对象是向量,它输出的结果为向量的秩,即排名。
当向量中出现重复值时,其排名将受到ties.method参数的影响。
ties.method参数一共有7种:
- average:默认值。平均排名,即对于重复值,分配它们在所有可能排名中的平均排名。例如,如果有两个并列第二的数值,则它们都会被赋予2.5的排名
- first:升序排名,即对于重复值,分配它们的最小可能排名。即,如果排名是从1开始的,则所有重复值都会被赋予它们原本可以占据的最小排名。
- last:降序排名,即对于重复值,分配它们的最大可能排名。即,如果排名是从1开始的,则所有重复值都会被赋予它们原本可以占据的最大排名。
- random:随机排名,即对于重复值,随机分配它们可能的排名之一。每次运行可能会得到不同的结果。
- max:最大排名,与last一致
- min:最小排名,与first一致
- dense:与"average"相似,但分配的是连续排名。即,如果有两个并列第二的数值,则下一个数值的排名将是第四,而不是跳过第三。
x <- c(4, 2, 2, 8, 3, 3, 1)
# 使用默认方法(即"average")
rank(x)
# 结果可能是: [1] 6.0 3.5 3.5 8.0 4.5 4.5 1.0
# 使用"first"方法
rank(x, ties.method = "first")
# 结果可能是: [1] 6 2 2 8 4 4 1
# 使用"last"方法
rank(x, ties.method = "last")
# 结果可能是: [1] 6 3 3 8 5 5 1
# 使用"dense"方法
rank(x, ties.method = "dense")
# 结果可能是: [1] 5 2 2 7 3 3 1
order()函数
用于返回向量中元素的排序索引。即order
函数不会直接改变向量的顺序,而是返回一个整数向量,该向量指定了原始向量中元素在排序后应该出现的位置。
order(x, decreasing = FALSE)
x
:一个数值向量、字符向量或因子向量。decreasing
:一个逻辑值,指定是否按降序排序。默认为FALSE
,即按升序排序。它返回一个整数向量,该向量给出了
x
中元素在排序前(升序或降序)的索引位置
x <- c(4, 2, 8, 3, 1)
# 按升序排序
sorted_indices <- order(x)
sorted_indices
# 结果可能是: [1] 5 2 4 1 3;因为元素1最开始的索引是5,元素2最开始的索引是2,依次类推(这里有点绕)
# 使用排序索引获取排序后的向量
sorted_x <- x[sorted_indices]
sorted_x
# 结果: [1] 1 2 3 4 8
# 按降序排序
sorted_indices_desc <- order(x, decreasing = TRUE)
sorted_indices_desc
# 结果可能是: [1] 3 1 4 2 5
# 使用排序索引获取降序排序后的向量
sorted_x_desc <- x[sorted_indices_desc]
sorted_x_desc
# 结果: [1] 8 4 3 2 1
六、增加数据
with()函数:增加一列数据
作用是对当前数据构建一个环境,并在该环境中计算表达式。
tips1 <- tips
# 在tips1中增加一列cost(总消费)
tips1$cost <- with(tips1, total_bill + tip)
head(tips1)
# 使用$符号
tips1$cost <- tips$total_bill + tips$tip
within()和transform()函数:增加多列数据
tips2 <- tips
# 增加两列数据:总消费cost和人均消费avg.cost
tips2 <- within(tips2,
{
cost=total_bill + tip
avg.cost=cost/size
})
head(tips2)
within()函数中新生成的变量(上例中的cost)可以被后续的代码调用,而trnasform()函数新生成的变量则无法被后续的代码调用,如下所示:
tips3 <- tips
tips3 <- transform(tips3, cost=total_bill + tip, avg.cost=cost/size)
tips3 <- tips
tips3 <- transform(tips3, cost=total_bill + tip, avg.cost=(total_bill+tip)/size)