欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《R语言实战》学习记录:基本数据管理

程序员文章站 2022-03-22 23:24:10
...

时间: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)

《R语言实战》学习记录:基本数据管理
方法二:
使用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语言