《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

猜你喜欢

转载自blog.csdn.net/woooooood/article/details/81910438