《R语言实战》学习记录:基本数据管理
时间:2018-08-14(学习) 2018-08-16(记录)
教程:《R语言实战》
学习内容:第四章
R语言实战
第四章:基本数据管理
1. 添加变量
生成数据框后可以为数据框添加新的变量。
eg:
方法一:
直接为原有数据框添加新变量:
> mydata1 <- data.frame(x1 = c(2, 2, 6, 4), x2 = c(3, 4, 2, 8))
> mydata1$sumx <- mydata1$x1 + mydata1$x2
> mydata1$meanx <- (mydata1$x1 + mydata1$x2)/2
方法二:
使用transform函数为数据框添加新变量:
格式:transform(原数据, 新变量1名称 = 公式, 新变量2名称 = 公式, …)
> mydata2 <- data.frame(x1 = c(2, 2, 6, 4), x2 = c(3, 4, 2, 8))
> mydata2 <- transform(mydata2, sumx = x1 + x2, meanx = (x1 + x2)/2)
> all(mydata1 == mydata2)
[1] TRUE
生成本章节所使用的数据:
> manager <- c(1, 2, 3, 4, 5)
> date <- c("10/24/08", "10/28/08", "10/1/08", "10/12/08", "5/1/09")
> country <- c("US", "US", "UK", "UK", "UK")
> gender <- c("M", "F", "F", "M", "F")
> age <- c(32, 45, 25, 39, 99) # age中缺失值用99表示
> q1 <- c(5, 3, 3, 3, 2)
> q2 <- c(4, 5, 5, 3, 2)
> q3 <- c(5, 2, 5, 4, 1)
> q4 <- c(5, 5, 5, NA, 2)
> q5 <- c(5, 5, 2, NA, 1)
> leadership <- data.frame(manager, date, country, gender, age,
+ q1, q2, q3, q4, q5, stringsAsFactors = FALSE)
> rm("manager", "date", "country", "gender", "age", "q1", "q2", "q3", "q4", "q5")
R中可以根据原有变量的现存值创建新的变量。
如:
对数据框leadership添加新的变量agecat,按年龄对其进行赋值,75以上为老年,55-75为中年,55以下为青年。由于该数据框中年龄的缺失值用99表示,因此在添加新变量agecat前应当将99改为缺失值,以免出现错误。
variable[condition] <- expression :仅在 condition 的值为”TRUE”时执行赋值。
方法一:
> leadership$age[leadership$age == 99] <- NA
> leadership$agecat[leadership$age > 75] <- "Elder"
> leadership$agecat[leadership$age >= 55 &
+ leadership$age <= 75] <- "Middle Aged"
> leadership$agecat[leadership$age < 55] <- "Young"
方法二:
> leadership <- within(leadership, {
+ age[age == 99] <- NA
+ agecat <- NA
+ agecat[age > 75] <- "Elder"
+ agecat[age >=55 & age <=55] <- "Middle Aged"
+ agecat[age < 55] <- "Young"
+ })
(within函数和with函数的区别在于:within函数允许修改数据框,为其添加新变量,而with函数不允许。)
结果:
> leadership
manager date country gender age q1 q2 q3 q4 q5 agecat
1 1 10/24/08 US M 32 5 4 5 5 5 Young
2 2 10/28/08 US F 45 3 5 2 5 5 Young
3 3 10/1/08 UK F 25 3 5 5 5 2 Young
4 4 10/12/08 UK M 39 3 3 4 NA NA Young
5 5 5/1/09 UK F NA 2 2 1 2 1 <NA>
可以看出,通过上述两种方法我们得到了想要的新变量agecat,且age中的99改为了缺失值,其对应的agecat也为缺失值。
> class(leadership$agecat)
[1] "character"
通过上述两个方法,我们得到的新变量agecat为字符型向量,而很明显,该变量为顺序数据,为因子变量更为合适。car包中的recode函数、doBy包中的recodevar函数以及cut函数可以帮我们达到这个目的。
本章节的学习中,使用recode函数对其进行转换。
eg:
> library(car)
> leadership$agecat <- recode(leadership$agecat,
+ "'Young' = 'Young';'Middle Aged' = 'Middle Aged';'Elder' = 'Elder'",
+ as.factor = TRUE,
+ levels = c("Young", "Middle Aged", "Elder"))
> class(leadership$agecat)
[1] "factor"
上述recode函数的使用中第二个参数的意思是原变量中的”Young”变为”Young”,”Middle Aged”变为”Middle Aged”,”Elder”变为”Elder”,该参数中等式左边为变量原内容,右边为变更后的内容,如果变量中的内容为数字1、2、3、4,要将变量中1、2便为”Young”,3变为”Middle Aged”, 4变为”Elder”,我们需要将第二个参数改为”c(1,2) = ‘Young’; 3 = ‘Middle Aged’;else = ‘Elder’”。
2.更改变量名称
R中可以对数据框中变量名称进行更改。
eg:
使用names函数可以显示某数据框当前的变量名称。
> names(leadership)
[1] "manager" "date" "country" "gender" "age" "q1"
[7] "q2" "q3" "q4" "q5" "agecat"
方法一:
fix(数据框):打开数据编辑器,手动点击进行修改即可。
> fix(leadership)
方法二:
使用reshape包中的rename函数对变量名称进行修改。
reshape包:数据集结构修改函数
格式:rename(dataframe, c(oldname = “newname”, oldname = “newname”, …))
eg:
> library(reshape)
> leadership <- rename(leadership,
+ c(manager = "managerID1", date = "textDate1"))
> names(leadership)
[1] "managerID1" "textDate1" "country" "gender" "age"
[6] "q1" "q2" "q3" "q4" "q5"
[11] "agecat"
可以看出,第一个和第二个变量的名称变为从”manager”和”date”变为了”managerID1”和”textDate1”
方法三:
通过names函数除了可以查看变量名以外还可以通过该函数更改变量名,即对其进行重新赋值。
eg:
> names(leadership)[c(1,2)] <- c("managerID", "textDate")
> names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5")
> names(leadership)
[1] "managerID" "textDate" "country" "gender" "age"
[6] "item1" "item2" "item3" "item4" "item5"
[11] "agecat"
3.缺失值的处理
使用is.na函数可以确认数据是否为缺失值,但该函数是对数据内容一一对应来确认的,数据为缺失值则返回”TRUE”,不是则为”FALSE”。如果变量中数据不止一个,则会返回一个逻辑值向量,因此如果想要查看一个变量中是否含有缺失值,我们需要对其套用all函数,如果含有缺失值,则返回”FALSE”,否则为”TRUE”
eg:
> is.na(leadership[, 6:10])
item1 item2 item3 item4 item5
[1,] FALSE FALSE FALSE FALSE FALSE
[2,] FALSE FALSE FALSE FALSE FALSE
[3,] FALSE FALSE FALSE FALSE FALSE
[4,] FALSE FALSE FALSE TRUE TRUE
[5,] FALSE FALSE FALSE FALSE FALSE
> all(is.na(leadership[, 6:10]))
[1] FALSE
缺失值是不可以比较的,已知leadership中第4行第8列的内容为4,第4行第9列的内容为NA,即缺失值.
> leadership[4,8] == 4
[1] TRUE
> leadership[4,9] == NA
[1] NA
因此,变量内容是否为缺失值无法通过等号比较来确认。
对于求和函数sum,如果想要对某含有缺失值的变量求和,需要对其参数na.rm赋值为”TRUE”。
eg:
> sum(leadership[4, 6:10])
[1] NA
> sum(leadership[4, 6:10], na.rm = TRUE)
[1] 10
使用na.omit函数可以去除数据集中含有缺失值的行。
eg:
> leadership
managerID textDate country gender age item1 item2 item3 item4 item5
1 1 10/24/08 US M 32 5 4 5 5 5
2 2 10/28/08 US F 45 3 5 2 5 5
3 3 10/1/08 UK F 25 3 5 5 5 2
4 4 10/12/08 UK M 39 3 3 4 NA NA
5 5 5/1/09 UK F NA 2 2 1 2 1
agecat
1 Young
2 Young
3 Young
4 Young
5 <NA>
> newdata <- na.omit(leadership)
> newdata
managerID textDate country gender age item1 item2 item3 item4 item5
1 1 10/24/08 US M 32 5 4 5 5 5
2 2 10/28/08 US F 45 3 5 2 5 5
3 3 10/1/08 UK F 25 3 5 5 5 2
agecat
1 Young
2 Young
3 Young
可以看出,新生成的数据集newdata中去掉了原数据集leadership中含有缺失值的第4、5行。
4.日期
使用as.Date函数可以将字符形的日期转为日期类型。
格式:as.Date(“date“, “format“)
eg:
> mydates <- as.Date(c("2007-06-22","2004-02-13"))
> class(mydates)
[1] "Date"
> strDates <- c("01/05/1965","08/16/1975")
> myformat1 <- "%m/%d/%Y"
> as.Date(strDates, myformat1)
[1] "1965-01-05" "1975-08-16"
> myformat <- "%m/%d/%y"
> leadership$textDate <- as.Date(leadership$textDate, myformat)
> leadership$textDate
[1] "2008-10-24" "2008-10-28" "2008-10-01" "2008-10-12" "2009-05-01"
使用Sys.Date函数可以得到当前的日期(year-month-day),使用date函数可以得到当前的时间(周 月 日 时:分:秒 年)
format():接受一个参数,并按某种格式输出结果
eg:
> Sys.Date()
[1] "2018-08-16"
> date()
[1] "Thu Aug 16 15:27:38 2018"
> today <- Sys.Date()
> format(today, format = "%B %d %Y")
[1] "八月 16 2018"
> format(as.Date("1956-10-12"), format = "%A")
[1] "星期五"
R中的时间是以某时间距离1970年1月1日的秒数来存储的,因此,时间/日期可以进行计算。
使用difftime函数可以按秒(“secs”)、分(“mins”)、时(“hours”)、天(“days”)、周(“weeks”)来计算两个时间的差。
eg:
> startdate <- as.Date("2018-08-12")
> enddate <- as.Date("2018-08-30")
> days <- enddate - startdate
> days
Time difference of 18 days
> today <- Sys.Date()
> dob <- as.Date("1990-08-10")
> difftime(today, dob, units = "auto")
Time difference of 10233 days
> # units = “auto”/“secs”/“mins”/“hours”/“days”/“weeks”
5.排序
使用merge函数对数据进行排序。该函数默认的排序顺序是升序,如果想要按降序排序,需要在排序变量前加减号。
eg:
> newdata2 <- leadership[order(leadership$gender,-leadership$age),]
> newdata2
managerID textDate country gender age item1 item2 item3 item4 item5
2 2 2008-10-28 US F 45 3 5 2 5 5
3 3 2008-10-01 UK F 25 3 5 5 5 2
5 5 2009-05-01 UK F NA 2 2 1 2 1
4 4 2008-10-12 UK M 39 3 3 4 NA NA
1 1 2008-10-24 US M 32 5 4 5 5 5
agecat
2 Young
3 Young
5 <NA>
4 Young
1 Young
可以看出,新数据集按性别(M>F)为第一排序变量进行升序,按年龄为第二排序变量进行降序排列。
6.合并
使用merge函数可以对两个数据集以内联结的形式进行横向合并。
eg:
> Data1 <- data.frame(ID = c(12, 15, 17, 18, 19),
+ Country = c("UA", "UK", "China", "China", "Korea"),
+ Gender = c("Female", "Male", "Male", "Female", "Female"))
> Data1
ID Country Gender
1 12 UA Female
2 15 UK Male
3 17 China Male
4 18 China Female
5 19 Korea Female
> Data2 <- data.frame(ID = c(17, 18, 19), age = c(23, 34, 28))
> Data2
ID age
1 17 23
2 18 34
3 19 28
> total <- merge(Data1, Data2, by = "ID")
> total
ID Country Gender age
1 17 China Male 23
2 18 China Female 34
3 19 Korea Female 28
如果只是想要把两个数据集按行或按列连起来,使用cbind函数和rbind函数即可。
6.选取子集
如果想要删除某变量,需要对该变量赋值为NULL,而不能赋值为NA。
eg:
> Data1$Gender <- NA
> Data1
ID Country Gender
1 12 UA NA
2 15 UK NA
3 17 China NA
4 18 China NA
5 19 Korea NA
> Data1$Gender <- NULL
> Data1
ID Country
1 12 UA
2 15 UK
3 17 China
4 18 China
5 19 Korea
R中可以通过一些函数对数据集取子集:
方法一:使用name函数(丢弃变量)
> myvars <- names(Data1) %in% c("ID")
> Data1[!myvars]
Country
1 UA
2 UK
3 China
4 China
5 Korea
> myvars
[1] TRUE FALSE
> all(Data1[!myvars] == Data1[!c(TRUE, FALSE)])
[1] TRUE
通过上述代码及结果可以大致看出该方法的原理。
方法二:选入变量
> newdata3 <- leadership[which(leadership$gender == "M" &
+ leadership$age > 30),]
> newdata3
managerID textDate country gender age item1 item2 item3 item4 item5
1 1 2008-10-24 US M 32 5 4 5 5 5
4 4 2008-10-12 UK M 39 3 3 4 NA NA
agecat
1 Young
4 Young
# 选取数据集leadership中在2009年1月到10月31日期间的数据
> startdate <- as.Date("2009-01-01")
> enddate <- as.Date("2009-10-31")
> newdata5 <- leadership[which(leadership$textDate >= startdate &
+ leadership$textDate <= enddate),]
> newdata5
managerID textDate country gender age item1 item2 item3 item4 item5
5 5 2009-05-01 UK F NA 2 2 1 2 1
agecat
5 <NA>
*方法三:*subset函数
# 从leadership中选取年龄大于等于35或小于24的行,并输出选中行中的变量item1, item2, item3, item4的列
> subset(leadership, age >=35 | age < 24,
+ select = c(item1, item2, item3, item4))
item1 item2 item3 item4
2 3 5 2 5
4 3 3 4 NA
# 从leadership中选取性别为男且年龄大于25的行,并输出选中行中的变量gender到item2的列
> subset(leadership, gender == "M" & age > 25,
+ select = gender: item2)
gender age item1 item2
1 M 32 5 4
4 M 39 3 3
使用sample函数随机抽取数据
eg:
# 从leadership中的1:nrow(leadership)行中随机抽取3列,不允许重复
leadership[sample(1:nrow(leadership), 3, replace = FALSE)]
textDate country age
1 2008-10-24 US 32
2 2008-10-28 US 45
3 2008-10-01 UK 25
4 2008-10-12 UK 39
5 2009-05-01 UK NA
上一篇: R语言实战记录----图形记录
下一篇: 《R语言实战》学习记录:图形初阶