zoukankan      html  css  js  c++  java
  • R语言Data Frame数据框常用操作

    Data Frame一般被翻译为数据框,感觉就像是R中的表,由行和列组成,与Matrix不同的是,每个列可以是不同的数据类型,而Matrix是必须相同的。

    Data Frame每一列有列名,每一行也可以指定行名。如果不指定行名,那么就是从1开始自增的Sequence来标识每一行。

    初始化

    使用data.frame函数就可以初始化一个Data Frame。比如我们要初始化一个student的Data Frame其中包含ID和Name还有Gender以及Birthdate,那么代码为:
    student<-data.frame(ID=c(11,12,13),Name=c("Devin","Edward","Wenli"),Gender=c("M","M","F"),Birthdate=c("1984-12-29","1983-5-6","1986-8-8”))
    另外也可以使用read.table() read.csv()读取一个文本文件,返回的也是一个Data Frame对象。读取数据库也是返回Data Frame对象。
    查看student的内容为:
      ID   Name Gender  Birthdate
    1  11  Devin      M 1984-12-29
    2  12 Edward      M   1983-5-6
    3  13  Wenli      F   1986-8-8
    这里只指定了列名为ID,Name,Gender和Birthdate,使用names函数可以查看列名,如果要查看行名,需要用到row.names函数。这里我们希望将ID作为行名,那么可以这样写:
    row.names(student)<-student$ID
    更简单的办法是在初始化date.frame的时候,有参数row.names可以设置行名的向量。

    访问元素

    与Matrix一样,使用[行Index,列Index]的格式可以访问具体的元素。
    比如访问第一行:
    student[1,]
    访问第二列:
    student[,2]
    使用列的Index或者列名可以选取要访问的哪些列。比如要ID和Name,那么代码为:
    idname<-student[1:2]
    或者是
    idname<-student[c("ID","Name”)]
    如果是只访问某一列,返回的是Vector类型的,那么可以使用[[或者$来访问。比如我们要所有student的Name,代码为:
    name<-student[[2]] 或者name<-student[[“Name”]] 或者name<-student$Name
    使用attach和detach函数可以使得访问列时不需要总是跟着变量名在前面。
    比如要打印所有Name,那么可以写成:
    attach(student)
    print(Name)
    detach(student)
    还可以换一种简洁一点的写法就是用with函数:
    with(student,{
      n<-Name
      print(n)
    })
    这里的n作用域只在大括号内,如果想在with函数中对全局的变量进行赋值,那么需要使用<<-这样一个运算符。

    修改列数据类型

    接下来我们查看该对象每列的类型,使用str(student)可以得到如下结果:
    'data.frame':3 obs. of  4 variables:
     $ ID       : num  1 2 3
     $ Name     : Factor w/ 3 levels "Devin","Edward",..: 1 2 3
     $ Gender   : Factor w/ 2 levels "F","M": 2 2 1
     $ Birthdate: Factor w/ 3 levels "1983-5-6","1984-12-29",..: 2 1 3
    默认情况下,字符串向量都会被自动识别成Factor,也就是说,ID是数字类型,其他的3个列都被定义为Factor类型了。显然这里Name应该是字符串类型,Birthdate应该是Date类型,我们需要对列的数据类型进行更改:
    student$Name<-as.character(student$Name)
    student$Birthdate<-as.Date(student$Birthdate)
    下面我们再运行str(student)看看修改后的结果:
    'data.frame':3 obs. of  4 variables:
     $ ID       : num  11 12 13
     $ Name     : chr  "Devin" "Edward" "Wenli"
     $ Gender   : Factor w/ 2 levels "F","M": 2 2 1
     $ Birthdate: Date, format: "1984-12-29" "1983-05-06" "1986-08-08”

    添加新列

    对于以及存在的student对象,我们希望增加Age列,该列是根据Birthdate算出来的。首先需要知道怎么算年龄。我们可以使用日期函数Sys.Date()获得当前的日期,然后使用format函数获得年份,然后用两个年份相减就是年龄。好像R并没有提供几个能用的日期函数,我们只能使用format函数取出年份部分,然后转换为int类型相减。
    student$Age<-as.integer(format(Sys.Date(),"%Y"))-as.integer(format(student$Birthdate,"%Y”))
    这样写似乎太长了,我们可以用within函数,这个函数和之前提到过的with函数类似,可以省略变量名,不同的地方是within函数可以在其中修改变量,也就是我们这里增加Age列:
    student<-within(student,{
      Age<-as.integer(format(Sys.Date(),"%Y"))-as.integer(format(Birthdate,"%Y"))
    })

    查询/子集

    查询一个Date Frame,返回一个满足条件的子集,这相当于数据库中的表查询,是非常常见的操作。使用行和列的Index来获取子集是最简单的方法,前面已经提到过。如果我们使用布尔向量,配合which函数,可以实现对行的过滤。比如我们要查询所有Gender为F的数据,那么我们首先对student$Gender==“F”,得到一个布尔向量:FALSE FALSE  TRUE,然后使用which函数可以将布尔向量中TRUE的Index返回,所以我们的完整查询语句就是:
    student[which(student$Gender=="F"),]
    注意这里列Index并没有输入,如果我们只想知道所有女生的年龄,那么可以改为:
    student[which(student$Gender=="F"),"Age”]
    这样的查询写法还是复杂了点,可以直接使用subset函数,那么查询会简单些,比如我们把查询条件改为年龄<30的女性,查姓名和年龄,那么查询语句为:
    subset(student,Gender=="F" & Age<30 ,select=c("Name","Age"))
    使用SQL查询Data Frame
    对于我这种使用了多年SQL的人来说,如果能够直接写SQL语句对Data Frame进行查询操作,那是多么方便美妙的啊,结果还真有这么一个包:sqldf。
    同样是前面的需求,对应的语句就是:
    library(sqldf)
    result<-sqldf("select Name,Age from student where Gender='F' and Age<30")

    连接/合并

    对于数据库来说,对多表进行join查询是一个很正常的事情,那么在R中也可以对多个Data Frame进行连接,这就需要使用merge函数。
    比如除了前面申明的student对象外,我们再申明一个score变量,记录了每个学生的科目和成绩:
    score<-data.frame(SID=c(11,11,12,12,13),Course=c("Math","English","Math","Chinese","Math"),Score=c(90,80,80,95,96))
    我们看看该表的内容:
      SID  Course Score
    1  11    Math    90
    2  11 English    80
    3  12    Math    80
    4  12 Chinese    95
    5  13    Math    96
    这里的SID就是Student里面的ID,相当于一个外键,现在要用这个ID进行inner join操作,那么对应的R语句就是:
    result<-merge(student,score,by.x="ID",by.y="SID")
    我们看看merge以后的结果:
     ID   Name Gender  Birthdate Age  Course Score
    1 11  Devin      M 1984-12-29  31    Math    90
    2 11  Devin      M 1984-12-29  31 English    80
    3 12 Edward      M 1983-05-06  32    Math    80
    4 12 Edward      M 1983-05-06  32 Chinese    95
    5 13  Wenli      F 1986-08-08  29    Math    96
    正如我们期望的一样join在了一起。
    除了join,另外一个操作就是union,这也是数据库常用操作,那么在R中如何将两个列一样的Data Frame Union联接在一起呢?虽然R语言中有union函数,但是不是SQL的Union的意思,我们要实现Union功能,需要用到rbind函数。
    rbind的两个Data Frame必须有相同的列,比如我们再申明一个student2,将两个变量rbind起来:
    student2<-data.frame(ID=c(21,22),Name=c("Yan","Peng"),Gender=c("F","M"),Birthdate=c("1982-2-9","1983-1-16"),Age=c(32,31))
    rbind(student,student2)
  • 相关阅读:
    【BZOJ 4581】【Usaco2016 Open】Field Reduction
    【BZOJ 4582】【Usaco2016 Open】Diamond Collector
    【BZOJ 4580】【Usaco2016 Open】248
    【BZOJ 3754】Tree之最小方差树
    【51Nod 1501】【算法马拉松 19D】石头剪刀布威力加强版
    【51Nod 1622】【算法马拉松 19C】集合对
    【51Nod 1616】【算法马拉松 19B】最小集合
    【51Nod 1674】【算法马拉松 19A】区间的价值 V2
    【BZOJ 2541】【Vijos 1366】【CTSC 2000】冰原探险
    【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
  • 原文地址:https://www.cnblogs.com/studyzy/p/R_DataFrame_Operation.html
Copyright © 2011-2022 走看看