列表数据框

数据分析
Author

hcl

Published

May 20, 2022

列表

  • 列表,可以包含不同类型的对象,甚至可以包括其他列表。

  • 列表的最大好处是,他能够将多个不同类型的对象打包到一起,使得可以根据位置和名字访问它们。

  • 常用场景:将函数的多个返回值打包到一起作为一个对象返回。

创建列表

  • 用list()将多个不同的对象创建为列表
l0 = list(1,c(TRUE,FALSE),c("a","b","C"))
l0
[[1]]
[1] 1

[[2]]
[1]  TRUE FALSE

[[3]]
[1] "a" "b" "C"
  • 在创建列表时,为列表的每个成分指定名字
l1 = list(A = 1, B = c(TRUE,FALSE),C = c("a","b","C"))
l1
$A
[1] 1

$B
[1]  TRUE FALSE

$C
[1] "a" "b" "C"
  • 创建列表后再对列表成分命名或修改名字:
names(l1) = NULL #移除列表成分的名字
names(l1) = c("x","y","z")

再来区分:[ ]与[[ ]]

  • [[ ]] 始终是提取一个元素的内容,列表某一个成分的内容(下一级元
    素)

  • [ ]始终是提取子集,列表的子集是包含若干成分的子列表(仍是同类
    型对象)

最常用的方法是用 $,通过成分名字来提取该成分下的内容:

l1$y
[1]  TRUE FALSE

用 [[n]] 来提取列表第 n 个成分的内容, n 也可以换成成分的名字:

l1[[2]]   #同l1[["y"]]
[1]  TRUE FALSE
提示

用 [[ ]] 提取列表中某个成分的内容更加灵活,可用在函数调用中,通过参数来传递成分索引或名字

p = "y"    #想要提取其内容的成分名字
l1[[p]]
[1]  TRUE FALSE

提取列表子集

  • 用 [ ],可以取出列表中的一些成分,作为一个新的(子)列表。

  • [ ]中可以用字符向量表示成分名字,用数值向量表示成分位置,或用逻
    辑向量指定是否选择,来取出列表成分

l1["x"]            #同l1[1]
$x
[1] 1
l1[c("x","z")]     #同l1[c(1,3)], l1[c(TRUE,FALSE,TRUE)]
$x
[1] 1

$z
[1] "a" "b" "C"

对列表的成分赋值

  • 先访问(提取)到列表的成分,再赋以相应的值
l1$x = 0   #将列表的成分x赋值为0
  • 同时给多个列表成分赋值
l1[c("x","y")] = list(x = "new value for x", y = c(3,1))
  • 移除列表的某些成分,只需赋值为NULL
l1[["z"]] = NULL

列表函数

  • as.list()将向量转换成列表
l2 = as.list(c(a = 1, b = 2))
l2
$a
[1] 1

$b
[1] 2
  • unlist()将一个列表打破成分界线,强制转换成一个向量
unlist(l2)
a b 
1 2 
笔记

tidyverse 系列中的 purrr 包为方便操作列表,提供了一系列操作列表的函数:

• pluck():同[[ ]]提取列表中的元素

• keep(): 保留满足条件的元素

• discard(): 删除满足条件的元素

• compact(): 删除列表中的空元素

• append():在列表末尾增加元素

• flatten(): 摊平列表(只摊平一层)

数据框

本质上讲,数据框就是一个列表,它的每个成分都是一个向量,并且长度相同,以表格的形式展现。总之, 数据框是由列向量组成、有着矩阵形式的列表 。
数据框与最常见的数据表是一致的:每一列代表一个变量属性,每一行代表一条样本数据 。

创建数据框

用tibble()根据若干列向量创建tibble:

library(tidyverse)
── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
✔ ggplot2 3.3.6      ✔ purrr   0.3.4 
✔ tibble  3.1.8      ✔ dplyr   1.0.10
✔ tidyr   1.2.1      ✔ stringr 1.4.1 
✔ readr   2.1.2      ✔ forcats 0.5.2 
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
persons = tibble(
  Name = c("Ken", "Ashley", "Jennifer"),
  Gender = c("Male", "Female", "Female"),
  Age = c(24, 25, 23),
  Major = c("Finance", "Statistics", "Computer Science")
  )
persons
# A tibble: 3 × 4
  Name     Gender   Age Major           
  <chr>    <chr>  <dbl> <chr>           
1 Ken      Male      24 Finance         
2 Ashley   Female    25 Statistics      
3 Jennifer Female    23 Computer Science

用as_tibble()将data.frame,matrix各成分等长度的list转换为tibble。

对数据框的各列重命名:

df = tibble(id = 1:4,
            levels = c(0,2,1,-1),
            score = c(0.5,0.2,0.2,0.5))
names(df) = c("id","x","y")
df
# A tibble: 4 × 3
     id     x     y
  <int> <dbl> <dbl>
1     1     0   0.5
2     2     2   0.2
3     3     1   0.2
4     4    -1   0.5

提取数据框的元素、子集

数据框是由列向量组成、有着矩阵形式的列表,所以可以用两种操作方式来访问数据框的元素和子集。

(1)以列表方式提取数据框的元素、子集

用$按列名来提取某一列的值,或者用[[ ]]按照位置或列名提取

df$x    #同df[["X"]],df[[2]]
[1]  0  2  1 -1

用[ ]提取数据框的一列或多列,得到子数据框,其内可以是数值向量(列位置)、字符向量(列名)、逻辑向量(是否选择各列)。

df[1]    #提取第1列,同df[["id"]]
# A tibble: 4 × 1
     id
  <int>
1     1
2     2
3     3
4     4
df[1:2]  #同df[c("id","x")],df[c(TRUE,TRUE,FALSE)]
# A tibble: 4 × 2
     id     x
  <int> <dbl>
1     1     0
2     2     2
3     3     1
4     4    -1

(2)以矩阵方式提取数据框的元素、子集

以列表形式操作并不支持行选择。以矩阵方式操作更加灵活。同时支持选择行和列。即用 [i, j] 指定行或列来提取数据框子集, [ , ]
其内可以是数值向量、字符向量或者逻辑向量 。

  • 若行选择器为空,则只选择列(所有行)
df[,"x"]
# A tibble: 4 × 1
      x
  <dbl>
1     0
2     2
3     1
4    -1
df[, c("x","y")]  #同df[,2:3]
# A tibble: 4 × 2
      x     y
  <dbl> <dbl>
1     0   0.5
2     2   0.2
3     1   0.2
4    -1   0.5
  • 若列选择器为空,则只选择行(所有列)
df[c(1,3),]
# A tibble: 2 × 3
     id     x     y
  <int> <dbl> <dbl>
1     1     0   0.5
2     3     1   0.2
  • 同时选择行和列
df[1:3,c("id","x")]
# A tibble: 3 × 2
     id     x
  <int> <dbl>
1     1     0
2     2     2
3     3     1
  • 根据条件筛选行或列
df[df$y > 0.5, c("id","y")]
# A tibble: 0 × 2
# … with 2 variables: id <int>, y <dbl>
ind = names(df) %in% c("x","y","w")
df[1:2, ind]
# A tibble: 2 × 2
      x     y
  <dbl> <dbl>
1     0   0.5
2     2   0.2

给数据框赋值

给数据框赋值,就是选择要赋值的位置,再准备好同样大小且格式匹配的数据,赋值给那些位置即可,所以同样有列表方式和矩阵方式。

(1)以列表方式给数据框赋值

  • 用$或[[ ]]对数据框的1列赋值
df$y = c(0.6,0.3,0.2,0.4)
#同df[["y"]] = c(0.6,0.3,0.2,0.4)
  • 利用现有列,创建(计算)新列
df$z = df$x + df$y
df
# A tibble: 4 × 4
     id     x     y     z
  <int> <dbl> <dbl> <dbl>
1     1     0   0.6   0.6
2     2     2   0.3   2.3
3     3     1   0.2   1.2
4     4    -1   0.4  -0.6
df$z = as.character(df$z)
df
# A tibble: 4 × 4
     id     x     y z    
  <int> <dbl> <dbl> <chr>
1     1     0   0.6 0.6  
2     2     2   0.3 2.3  
3     3     1   0.2 1.2  
4     4    -1   0.4 -0.6 

用[]可以对数据框的1列或多列进行赋值

df["y"] = c(0.8, 0.5, 0.2, 0.4)
df[c("x", "y")] = list(level = c(1, 2, 1, 0),
                       score = c(0.1, 0.2, 0.3, 0.4))

(2)以矩阵方式给数据框赋值

以列表方式对数据框进行赋值时,也是只能访问列。若需要更加灵活地进行赋值操作,可以以矩阵方式进行。

df[1:3,"y"] = c(-1,0,1)
df[1:2,c("x","y")] = list(level = c(0,0),
                          score = c(0.9,1.0))

一些有用的函数

str()或glimpse()作用在R对象上,显示该对象的结果:

str(persons)
tibble [3 × 4] (S3: tbl_df/tbl/data.frame)
 $ Name  : chr [1:3] "Ken" "Ashley" "Jennifer"
 $ Gender: chr [1:3] "Male" "Female" "Female"
 $ Age   : num [1:3] 24 25 23
 $ Major : chr [1:3] "Finance" "Statistics" "Computer Science"

summary()作用在数据框/列表上,将生成各列/成分的汇总信息

summary(persons)
     Name              Gender               Age          Major          
 Length:3           Length:3           Min.   :23.0   Length:3          
 Class :character   Class :character   1st Qu.:23.5   Class :character  
 Mode  :character   Mode  :character   Median :24.0   Mode  :character  
                                       Mean   :24.0                     
                                       3rd Qu.:24.5                     
                                       Max.   :25.0                     

将数据框按行或列进行合并,可以用dplyr包提供的bind_rows()、bind_cols()替代rbind()、cbind()。

鄂ICP备2022016232号-1