R语言小白学习笔记9—数据整理

  • 笔记链接
  • 学习笔记9—数据整理
  • 9.1 cbind和rbind
  • 9.2 连接
  • 9.3 reshape2
  • 9.3.1 melt函数
  • 9.3.2 dcast函数



学习笔记9—数据整理

在认真分析数据之前需要花费大量精力操作整理数据。

这章主要函数功能:将数据从面向列转变为面向行、多个数据合并为数据集

主要包:plyr、reshape2和data.table

9.1 cbind和rbind

最简单情况是两个数据集有相同列或相同行这时可用cbind或rbind函数

例:先用cbind合并几个向量,再用rbind将它们堆积

> sport <- c("Hockey", "Baseball", "Footall")
> league <- c("NHL", "MLB", "NFL")
> trophy <- c("Stanley Cup", "Commissioner's Trophy", "Vince Lombardi Trophy")
> trophies1 <- cbind(sport, league, trophy)
> trophies2 <- data.frame(sport=c("Basketball", "Golf"),
+                         league=c("NBA","PGA"),
+                         trophy=c("Larry O'Brien Championship Trophy", "Wanamaker Trophy"), 
+                         stringsAsFactors=FALSE)
> trophies <- rbind(trophies1, trophies2)

9.2 连接

当数据并不是很好地保持一致,以致不能简单地使用cbind时,可以使用merge(基本包)、join(plyr包)以及data.table中的合并功能。

例:将数据连接

1、下载和解压数据

> download.file(url="http://jaredlander.com/data/US_Foreign_Aid.zip", destfile = "E:/B/R/ForeignAid.zip")
> unzip("E:/B/R/ForeignAid.zip", exdir="data")
#这里用unzip解压后我打开文件夹发现没有解压成功,百度查了一下也没有啥解决方法,所以我直接鼠标解压了

2、用for循环,以编程方式加载文件。

dir得到一个文件列表,遍历文件列表,用assign函数为每一个数据集指定名称str_sub函数能从字符向量中抽取单个字符

> library(stringr)
> theFiles <- dir("E:/B/R/", pattern = "\\.csv")
> for(a in theFiles)
+ {
+     nameToUse <- str_sub(string=a, start=12, end=18)
+     temp <- read.table(file=file.path("E:/B/R", a),
+                        header=TRUE, sep=",", 
+                        stringsAsFactors = FALSE)
+     assign(x=nameToUse, value=temp)
+ }

3、合并

方法一:

R语言内置函数:meage,用于合并两个数据框

优点:对于每一个数据框可以指定不同的匹配列名

缺点:速度慢

> Aid90s00s <- merge(x=Aid_90s, y=Aid_00s,
+ by.x = c("Country.Name", "Program.Name"),
+ by.y = c("Country.Name", "Program.Name"))
#这里by.x是指定左边数据框的匹配列,by.y是指定右边数据框的匹配列。说白了就是让这两个数据框按着这几列进行匹配。
> head(Aid90s00s)
  Country.Name
1  Afghanistan
2  Afghanistan
3  Afghanistan
4  Afghanistan
5  Afghanistan
6  Afghanistan
                                       Program.Name
1                         Child Survival and Health
2         Department of Defense Security Assistance
3                            Development Assistance
4 Economic Support Fund/Security Support Assistance
5                                Food For Education
6                  Global Health and Child Survival
  FY1990 FY1991 FY1992   FY1993  FY1994 FY1995 FY1996
1     NA     NA     NA       NA      NA     NA     NA
2     NA     NA     NA       NA      NA     NA     NA
3     NA     NA     NA       NA      NA     NA     NA
4     NA     NA     NA 14178135 2769948     NA     NA
5     NA     NA     NA       NA      NA     NA     NA
6     NA     NA     NA       NA      NA     NA     NA
  FY1997 FY1998 FY1999 FY2000  FY2001   FY2002    FY2003
1     NA     NA     NA     NA      NA  2586555  56501189
2     NA     NA     NA     NA      NA  2964313        NA
3     NA     NA     NA     NA 4110478  8762080  54538965
4     NA     NA     NA     NA   61144 31827014 341306822
5     NA     NA     NA     NA      NA       NA   3957312
6     NA     NA     NA     NA      NA       NA        NA
      FY2004     FY2005     FY2006     FY2007     FY2008
1   40215304   39817970   40856382   72527069   28397435
2   45635526  151334908  230501318  214505892  495539084
3  180539337  193598227  212648440  173134034  150529862
4 1025522037 1157530168 1357750249 1266653993 1400237791
5    2610006    3254408     386891         NA         NA
6         NA         NA         NA         NA   63064912
      FY2009
1         NA
2  552524990
3    3675202
4 1418688520
5         NA
6    1764252

方法二:
plyr中的join

功能:合并数据框

优点:速度快

缺点:每一个表的匹配列名必须一样

例:

> Aid90s00sJoin <- join(x=Aid_90s, y=Aid_00s,
+ by=c("Country.Name", "Program.Name"))
> head(Aid90s00sJoin)
#这里结果和之前相同,我就不放结果了

4、多个合并

现在我们有8个数据框,想把它们合并为一个,而不用一个一个编码合并,这里采用把所有的数据框放进一个列表里,然后用Reduce函数把它们依次合并

例:

(1)、我们用str_sub函数为数据框重新建立一个名字,随后我们构建一个和数据库一样大的空列表,之后给列表取名,用遍历的方式把数据框放进列表

> frameNames <- str_sub(string=theFiles, start=12, end=18)
> frameList <- vector("list", length(frameNames))
> names(frameList) <- frameNames
> for(a in frameNames)
+ {
+     frameList[[a]] <- eval(parse(text=a))
+ }

(2)、用Reduce函数进行循环处理把元素连接起来

> allAid <- Reduce(function(...){
+     join(..., by=c("Country.Name", "Program.Name"))},
+     frameList
+ )
#元素是…意味着任何东西都可以传递给函数
> dim(allAid)
[1] 2453   67

5、合并表

这里我们用data.table中的合并表方法

例:

首先,把数据框转变为表格

> dt90 <- data.table(Aid_90s, key=c("Country.Name", "Program.Name"))
> dt00 <- data.table(Aid_00s, key=c("Country.Name", "Program.Name"))

进行连接

> dt0090 <- dt90[dt00]

这时dt90在左边,采用左连接合并

9.3 reshape2

下一个最常用的需求是融合数据(从列取向变成行取向)或者铸造数据(从行取向变成列取向),这里主要用reshape2包

9.3.1 melt函数

观察Aid_00s数据框,发现每一年数据储存在每一列中,不适合画图。

数据:

> head(Aid_00s,5)
  Country.Name
1  Afghanistan
2  Afghanistan
3  Afghanistan
4  Afghanistan
5  Afghanistan
                                       Program.Name
1                         Child Survival and Health
2         Department of Defense Security Assistance
3                            Development Assistance
4 Economic Support Fund/Security Support Assistance
5                                Food For Education
  FY2000  FY2001   FY2002    FY2003     FY2004
1     NA      NA  2586555  56501189   40215304
2     NA      NA  2964313        NA   45635526
3     NA 4110478  8762080  54538965  180539337
4     NA   61144 31827014 341306822 1025522037
5     NA      NA       NA   3957312    2610006
      FY2005     FY2006     FY2007     FY2008     FY2009
1   39817970   40856382   72527069   28397435         NA
2  151334908  230501318  214505892  495539084  552524990
3  193598227  212648440  173134034  150529862    3675202
4 1157530168 1357750249 1266653993 1400237791 1418688520
5    3254408     386891         NA         NA         NA

所以我们想将其设置为每一行代表一个单独的城市-项目-年,并且把美元金额存在一列。用到melt函数。

> melt00 <- melt(Aid_00s, id.vars = c("Country.Name", "Program.Name"), variable.name = "Year", value.name = "Dollars")
#这里的id.vars参数用来指定哪一列唯一地标识一行
> tail(melt00, 10)
      Country.Name
24521     Zimbabwe
24522     Zimbabwe
24523     Zimbabwe
24524     Zimbabwe
24525     Zimbabwe
24526     Zimbabwe
24527     Zimbabwe
24528     Zimbabwe
24529     Zimbabwe
24530     Zimbabwe
                                                Program.Name
24521                       Migration and Refugee Assistance
24522                                      Narcotics Control
24523 Nonproliferation, Anti-Terrorism, Demining and Related
24524                            Other Active Grant Programs
24525                                Other Food Aid Programs
24526                                 Other State Assistance
24527                                 Other USAID Assistance
24528                                            Peace Corps
24529                                                Title I
24530                                               Title II
        Year   Dollars
24521 FY2009   3627384
24522 FY2009        NA
24523 FY2009        NA
24524 FY2009   7951032
24525 FY2009        NA
24526 FY2009   2193057
24527 FY2009  41940500
24528 FY2009        NA
24529 FY2009        NA
24530 FY2009 174572685

接下来就可以进行作图,分开作图让我们很快就能发现和明白资助每一个项目的趋势

> ggplot(meltAgg, aes(x=Year, y=Dollars)) + 
+     geom_line(aes(group=Program.Name)) + 
+     facet_wrap(~ Program.Name) + 
+     scale_x_continuous(breaks=seq(from=2000, to=2009, by=2)) + 
+     theme(axis.text.x=element_text(angle=90, vjust=1,hjust=0)) + 
+     scale_y_continuous(labels=multiple_format(extra=dollar, multiple="B"))

r语言 某列中元素分类 r语言中分类汇总_数据

(刚开始一直报错,后来发现没加载包:ggplot在ggplot2包里,multiple_format这个函数在useful包里,如果不知道哪个函数在哪个包里边,可以用以下方法:
已安装包且已加载:? function_name
已安装包但未加载:? ?function_name
未安装:sos::findFn(“function_name”)或者百度、谷歌 R function_name(sos包)
方法来自知乎:stone)

9.3.2 dcast函数

接下来我们把融化的数据变回一般的格式。

dcast函数第一个参数是要用的数据第二个参数是公式,公式左边的列名依然作列,表达式右边的列名变为行,第三个参数是列,代表着公式右边参数的唯一值

> cast00 <- dcast(melt00, Country.Name + Program.Name ~ Year, value.var="Dollars")
> head(cast00)
  Country.Name
1  Afghanistan
2  Afghanistan
3  Afghanistan
4  Afghanistan
5  Afghanistan
6  Afghanistan
                                       Program.Name 2000
1                         Child Survival and Health   NA
2         Department of Defense Security Assistance   NA
3                            Development Assistance   NA
4 Economic Support Fund/Security Support Assistance   NA
5                                Food For Education   NA
6                  Global Health and Child Survival   NA
     2001     2002      2003       2004       2005
1      NA  2586555  56501189   40215304   39817970
2      NA  2964313        NA   45635526  151334908
3 4110478  8762080  54538965  180539337  193598227
4   61144 31827014 341306822 1025522037 1157530168
5      NA       NA   3957312    2610006    3254408
6      NA       NA        NA         NA         NA
        2006       2007       2008       2009
1   40856382   72527069   28397435         NA
2  230501318  214505892  495539084  552524990
3  212648440  173134034  150529862    3675202
4 1357750249 1266653993 1400237791 1418688520
5     386891         NA         NA         NA
6         NA         NA   63064912    1764252