Learning R 5 - Lists and Data Frames

https://github.com/cccxm/deep-learning/tree/master/R/learning-r/c-5

章节目标

  • 能够创建list和data.frame

  • 能够使用length,names以及一些其他的检查和操作这些变量的函数

  • 理解什么是NULL以及如何使用它

  • 理解递归变量和原子变量的不同

  • 了解关于list和data.frame的基本操作

文章目录

    • Lists
      • 创建链表
      • 原子变量和递归变量
      • 链表的长度与运算
      • 链表的索引操作
      • 链表和向量的转换
      • 链表的拼接
    • Data Frame
      • 创建数据框对象
      • 基本的数据框操作

Lists

List可以理解为其中元素类型可以不同的向量。

创建链表

使用list函数可以创建一个链表。

> my_list <- list(c(1,2,3),matrix(c(1,2,3,4),nrow = 2))
> my_list
[[1]]
[1] 1 2 3

[[2]]
     [,1] [,2]
[1,]    1    3
[2,]    2    4

和向量不同的是,链表中不会合并数据。

使用names函数可以给链表中的元素命名。

> names(my_list) <- c('vector','matrix')
> my_list
$vector
[1] 1 2 3

$matrix
     [,1] [,2]
[1,]    1    3
[2,]    2    4

除了使用names函数外,也可以在链表创建时指定名称

> my_list <- list(
+   vector=c(1,2,3),
+   matrix=matrix(1:4,nrow = 2)
+ )
> my_list
$vector
[1] 1 2 3

$matrix
     [,1] [,2]
[1,]    1    3
[2,]    2    4

原子变量和递归变量

由于链表的特性,链表中的元素仍然可以是一个链表,所以链表可以被认为是一个可递归的变量。

使用is.atomicis.recursive函数可以判断变量的类型

> is.atomic(list())
[1] FALSE
> is.atomic(numeric())
[1] TRUE

链表的长度与运算

链表的长度只与它顶层元素的数量有关。

> length(my_list)
[1] 2

链表不能像矩阵那样测量维度,行数,列数等信息,但是提供了一个类似名称的函数。

> nrow(my_list)
NULL
> NROW(my_list)
[1] 2
> NCOL(my_list)
[1] 1

木的灵魂的两个函数。

关于运算:链表不能像向量一样直接在其对象上运算。

> 1:4 + 2:5
[1] 3 5 7 9
> list(c(1:4))+list(c(2:5))

# Error in list(c(1:4)) + list(c(2:5)): 二进列运算符中有非数值参数

直接在链表上的运算会提示错误。

需要将待运算的数据转换成向量之后才能正常运算结果。例如

> list(c(1:4))[[1]]+list(c(2:5))[[1]]
[1] 3 5 7 9

链表的索引操作

假设链表结构如下

> my_list <- list(
+   first = 1,
+   second = 2,
+   thrid = list(
+     alpha = 3.1,
+     beta = 3.2
+   )
+ )

与向量操作类似,可以直接使用方括号形式的索引获取元素。

> my_list[1:2]
$first
[1] 1

$second
[1] 2

> my_list[-3]
$first
[1] 1

$second
[1] 2

> my_list['first']
$first
[1] 1

> my_list[c(T,F,F)]
$first
[1] 1

**注意:**以上通过索引方式获取的对象仍然是个链表。如果我们需要获取对应的内容,则需要使用双重中括号。

> typeof(my_list[1])
[1] "list"
> typeof(my_list[[1]])
[1] "double"

除了使用typeof输出类型的名称,还可以用逻辑运算函数is.list来判断当前是否是链表类型。

除了使用方括号索引获取对象,还可以使用$加名称查找对应的元素,注意:只要表示唯一,可以使用名字的简写。

> l <- list(
+   same1 = 1:4,
+   same2 = 5:8,
+   other = 9:12
+ )
> l$other
[1]  9 10 11 12
> l$o
[1]  9 10 11 12
> l$same
NULL

$符号的作用是取值,等价于双重中括号

> typeof(l['other']) == typeof(l$other)
[1] FALSE
> typeof(l[['other']]) == typeof(l$other)
[1] TRUE

链表和向量的转换

as.*函数可以实现类型的转换。

> as.list(1:4)
[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
[1] 3

[[4]]
[1] 4

> as.vector(list(1:4))
[[1]]
[1] 1 2 3 4

> as.vector(list(a=1:2,b=3:4))
$a
[1] 1 2

$b
[1] 3 4

> unlist(list(a=1:2,b=3:4))
a1 a2 b1 b2 
 1  2  3  4 

链表的拼接

c函数可以应用于链表表示拼接。使用方式如下

> com_list <- c(list(1:3), 4)
> com_list
[[1]]
[1] 1 2 3

[[2]]
[1] 4

> typeof(com_list)
[1] "list"

使用矩阵函数cbind或者rbind同样可以实现链表的拼接

> cbind(
+   list(a = 1, b = 2),
+   list(c = 3, d = 4)
+ )
  [,1] [,2]
a 1    3   
b 2    4   
> rbind(
+   list(a = 1, b = 2),
+   list(c = 3, d = 4)
+ )
     a b
[1,] 1 2
[2,] 3 4

Data Frame

数据框是一种表格结构的对象,与矩阵类似,但不要求类型相同。

创建数据框对象

使用data.frame函数就可创建一个数据框对象。

> data.frame(
+   x = 1,
+   y = 2:3,
+   z = 4:7
+ )
  x y z
1 1 2 4
2 1 3 5
3 1 2 6
4 1 3 7

基本的数据框操作

转置

> df <- data.frame(
+   x = 1,
+   y = 2:3,
+   z = 4:7
+ )
> df
  x y z
1 1 2 4
2 1 3 5
3 1 2 6
4 1 3 7
> t(df)
  [,1] [,2] [,3] [,4]
x    1    1    1    1
y    2    3    2    3
z    4    5    6    7

列合并

将一个数据框追加到另一个数据框的右侧

> df1 <- data.frame(
+   x = 1,
+   y = 2:3,
+   z = 4:7
+ )
> df2 <- data.frame(
+   a = letters[1:4],
+   b = letters[5:8]
+ )
> cbind(df1, df2)
  x y z a b
1 1 2 4 a e
2 1 3 5 b f
3 1 2 6 c g
4 1 3 7 d h

行合并

将两个数据框按照行扩展的方式追加

> df1 <- data.frame(
+   x = 1,
+   y = 2:3,
+   z = 4:7
+ )
> df2 <- data.frame(
+   x = 1:3,
+   y = 4:6,
+   z = 7:9
+ )
> rbind(df1, df2)
  x y z
1 1 2 4
2 1 3 5
3 1 2 6
4 1 3 7
5 1 4 7
6 2 5 8
7 3 6 9

有条件合并

> df1 <- data.frame(
+   names = c('apple', 'orange'),
+   price = c(6.9, 8.9)
+ )
> df2 <- data.frame(
+   names = c('apple', 'orange'),
+   color = c('red', 'orange')
+ )
> merge(df1, df2, by = 'names')
   names price  color
1  apple   6.9    red
2 orange   8.9 orange

你可能感兴趣的:(数据分析)