看了几本R语言语法相关的书籍,感觉都不怎么好,在实际使用过程中仍然遇到很多难以理解的问题,后来看了Hadley Wickham的Advanced R,好多问题迎刃而解,今天重温了该书的第一章即数据结构,记录下要点。干脆翻译下吧。

  原文地址:http://adv-r.had.co.nz/Data-structures.html

  本人水平有限,如有错误请谅解和指正,非常感谢。转载请注明出处:http://www.cnblogs.com/lizichao/p/4792373.html

数据结构

  这一章概述了base R中最重要的数据结构。你很可能之前使用过其中的一些(即使不是全部),但也许你没有深入思考它们是如何关联的。在这篇简短的概述中,我不会深入讨论每种类型。相反,我将展示它们是如何组成一个整体的。如果想了解更多的细节,可以参考R的文档。

  R的基础数据结构可以按照维数(1维、2维、或者多维)或者同质(所有元素都是同类型的)、非同质来划分。按照这种思路可以得到数据分析中使用最多的5种数据类型:

  同质 非同质
1维 原子向量 列表
2维 矩阵 数据框
多维 数组  

  几乎所有其他对象都是建立在这些类型之上。在the OO field guide中你将看到更加复杂对象是如何通过这些简单类型创建的。注意R没有0维或者标量类型。一个数或者字符串,你可能认为是标量的,但其实是长度为1的向量。

  给定一个对象,想要了解其数据结构的最好方式是使用str()函数。str()是structure的缩写,调用该函数将返回对R中任意数据结构的简洁、可读的描述。

测试

  做下这个小测试,以确定你是否需要阅读这一章。如果可以很快想到答案,你可以跳过这一章。可以在答案(译者注:位于本章结尾)中检验你的答案。

  1. 向量的3个属性是什么,不是类型?
  2. 原子向量的4种常见类型是哪4种?另外2中少见的类型是什么?
  3. 属性是什么?如何获取和设置属性?
  4. 列表与原子向量有何不同?矩阵与数据框有何不同?
  5. 列表是否可以是矩阵?矩阵是否可以作为数据框的一列?

概述

  • 向量,介绍原子向量和列表,属于R中1维的数据结构。
  • 属性,绕个弯儿,讨论下属性,R中灵活的元数据规范。你将学习到因子,一种通过设置原子向量创建的重要数据结构。
  • 矩阵和数组,介绍矩阵和数组,它们是2维和高维数据结构。
  • 数据框,介绍数据框,它是R中数据存储最重要的数据结构。数据框组合了列表和矩阵的行为,这使得数据框成为一种最适合存储统计数据的数据结构。

向量

  R的基础数据结构是向量。向量有2类:原子向量和列表。它们有3个共同的属性:

  • 类型,typeof(),表明它是什么。
  • 长度,length(),它有多少元素。
  • 属性,attributes(),附加的任意元数据。

  原子向量和列表的元素不同:原子向量的所有元素必须是同类型的,而列表的元素可以是不同类型的。

  注意:is.vector()不能验证一个对象是否是向量。相反,只有当对象除了names外没有其他属性时,该函数返回TRUE。测试一个对象是否是向量,使用is.atomic(x) || is.list(x)。

原子向量

  我将详细讨论4种常见类型的原子向量:逻辑向量,整形向量,双精度(常称为数值向量),字符向量。还有2种不常见类型的向量:复数向量和raw向量,这里不讨论这2种类型的向量。

  原子向量一般用c()创建,c是combine的缩写:

  1. dbl_var <- c(, 2.5, 4.5)
  2. # With the L suffix, you get an integer rather than a double
  3. int_var <- c(1L, 6L, 10L)
  4. # Use TRUE and FALSE (or T and F) to create logical vectors
  5. log_var <- c(TRUE, FALSE, T, F)
  6. chr_var <- c("these are", "some strings")

  原子向量总是扁平的,即使嵌套c():

  1. c(, c(, c(, )))
  2. #> []
  3. # the same as
  4. c(, , , )
  5. #> []

  缺失值用NA表示,NA是一个长度为1的逻辑向量。当NA出现在c()中时,它总能被强制转换为正确的类型,或者你可以创建特定类型的NAs,NA_real_ (一个双精度向量),NA_integer_NA_character_.

类型和测试

  给定一个向量,你可以用typeof()确定它的类型,或者使用“is”函数来检验它的具体类型:is.character(),is.double(),is.integer(),is.logical(),或者,更一般的, is.atomic()。

  1. int_var <- c(1L, 6L, 10L)
  2. typeof(int_var)
  3. #> [] "integer"
  4. is.integer(int_var)
  5. #> [] TRUE
  6. is.atomic(int_var)
  7. #> [] TRUE
  8.  
  9. dbl_var <- c(, 2.5, 4.5)
  10. typeof(dbl_var)
  11. #> [] "double"
  12. is.double(dbl_var)
  13. #> [] TRUE
  14. is.atomic(dbl_var)
  15. #> [] TRUE

  注意:is.numeric()是对数值型向量一般的测试,对于整形向量和双精度向量,它都返回TRUE。它不是对双精度向量的具体测试,双精度向量常被称为数值向量。

  1. is.numeric(int_var)
  2. #> [] TRUE
  3. is.numeric(dbl_var)
  4. #> [] TRUE

强制转换

  原子向量的所有元素都必须是同类型的,所以当你试图将不同类型组合到一起时,它们会被强制转换为最灵活的类型。最不灵活到最灵活类型的顺序是:逻辑、整形、双精度、字符。

  比如,组合字符和整形到一个原子向量,会得到一个字符向量:

  1. str(c("a", ))
  2. #> chr [:] "a" ""

  当逻辑向量强制转换为整形或者双精度向量时,TRUE变为1,FALSE变为0。这在联合使用sum()mean()时非常有用:

  1. x <- c(FALSE, FALSE, TRUE)
  2. as.numeric(x)
  3. #> []
  4.  
  5. # Total number of TRUEs
  6. sum(x)
  7. #> []
  8.  
  9. # Proportion that are TRUE
  10. mean(x)
  11. #> [] 0.3333333

  强制转换经常自动进行。绝大多数数学函数(+,log,abs,等)会强制转换为双精度和整形向量,大多数逻辑操作(&,|,any,等)会强制转换为逻辑向量。如果强制转换时发生信息丢失,一般你会得到一个警告信息。如果很可能造成困惑,可以显示使用as.character(),as.double(),as.integer(),或者as.logical()进行强制转换。

列表

  列表不同于原子向量,因为列表的元素可以是任意类型,包括列表。使用list()创建列表:

  1. x <- list(:, "a", c(TRUE, FALSE, TRUE), c(2.3, 5.9))
  2. str(x)
  3. #> List of
  4. #> $ : int [:]
  5. #> $ : chr "a"
  6. #> $ : logi [:] TRUE FALSE TRUE
  7. #> $ : num [:] 2.3 5.9

  列表有时被称为递归向量,因为列表可以包含其他列表。这使得列表在根本上不同于原子向量。

  1. x <- list(list(list(list())))
  2. str(x)
  3. #> List of
  4. #> $ :List of
  5. #> ..$ :List of
  6. #> .. ..$ : list()
  7. is.recursive(x)
  8. #> [] TRUE

  c()将多个列表合并为一个。当组合原子向量和列表时,c()将强制转换原子向量为列表,然后组合它们。比较list()和c()的结果:

  1. x <- list(list(, ), c(, ))
  2. y <- c(list(, ), c(, ))
  3. str(x)
  4. #> List of
  5. #> $ :List of
  6. #> ..$ : num
  7. #> ..$ : num
  8. #> $ : num [:]
  9. str(y)
  10. #> List of
  11. #> $ : num
  12. #> $ : num
  13. #> $ : num
  14. #> $ : num

  typeof()作用于列表时得到list。你可以用is.list()测试列表,用as.list()强制转换为列表,用unlist()将列表转换为原子向量。如果列表中的元素是不同类型的,unlist()使用与c()相同的强制转换规则。

  在R中,列表用来创建许多更加复杂的数据类型。比如,数据框(在data frames介绍)和线性模型对象(调用lm()函数产生)都是列表:

  1. is.list(mtcars)
  2. #> [] TRUE
  3.  
  4. mod <- lm(mpg ~ wt, data = mtcars)
  5. is.list(mod)
  6. #> [] TRUE

练习

  1. 原子向量的6种类型是?列表与原子向量有何不同?
  2. 为何is.vector()is.numeric()从根本上不同于is.list()和is.character()?
  3. 测试你关于向量强制转换规则的知识,请尝试预测下列使用c()代码的输出结果:
    1. c(, FALSE)
    2. c("a", )
    3. c(list(), "a")
    4. c(TRUE, 1L)

    4.  为何需要使用unlist()将列表转换为原子向量?为什么as.vector()不好使?

  5.  为什么1 == "1"为真?为什么-1 < FALSE为真?为什么"one" < 2为假?

  6.  为什么缺失值,NA,是一个逻辑向量?逻辑向量有什么特别的?(提示:思考c(FALSE, NA_character_))。

属性

  所有对象都可以有任意附加属性,可以用来存储对象的元数据。属性可以认为是一个命名的列表(有唯一的名称)。属性可以单独使用attr()来访问,或者使用attributes()一次性得到所有属性(以列表形式)。

  1. y <- :
  2. attr(y, "my_attribute") <- "This is a vector"
  3. attr(y, "my_attribute")
  4. #> [] "This is a vector"
  5. str(attributes(y))
  6. #> List of
  7. #> $ my_attribute: chr "This is a vector"

  structure()函数返回一个修改了属性的新对象:

  1. structure(:, my_attribute = "This is a vector")
  2. #> []
  3. #> attr(,"my_attribute")
  4. #> [] "This is a vector"

  默认情况下,修改一个向量时大多数属性都会丢失:

  1. attributes(y[])
  2. #> NULL
  3. attributes(sum(y))
  4. #> NULL

  唯一不会丢失的3个属性也是最重要的属性:

  • 名称,一个字符向量,给定了每个元素名称,在names中介绍。
  • 维度,用来将向量转换为矩阵和数组,在matrices and arrays中介绍。
  • 类,用来实现S3对象体系,在S3中介绍。

  这3个属性,都有具体的访问函数,可以获取和设置对应的属性值。对于这些属性,使用names(x)dim(x),和class(x),不要使用attr(x, "names"),attr(x, "dim"),和attr(x, "class")。

名称

  你可以使用3种方式命名向量:

  • 创建向量时:x <- c(a = 1, b = 2, c = 3)。
  • 在适当的地方修改已存在的向量:x <- 1:3; names(x) <- c("a", "b", "c")。
  • 创建一个向量的修改拷贝:x <- setNames(1:3, c("a", "b", "c"))。

  名称不必是唯一的。但是,取字符子集,在subsetting介绍,是使用名称的最重要原因,而且当名称唯一时最为有用。

  不是向量的所有元素都需要有名称。如果一些名称缺失, names()会为这些缺失名称的元素返回空字符串。如果所有元素都没有名称, names()返回NULL。

  1. y <- c(a = , , )
  2. names(y)
  3. #> [] "a" "" ""
  4.  
  5. z <- c(, , )
  6. names(z)
  7. #> NULL

  你可以使用unname(x)创建一个新的、没有名称的向量,或者在适当的地方移除名称,使用names(x) <- NULL。

因子

  属性的一个重要应用是定义因子。因子是只含有预定义值的向量,被用来存储分类数据。利用2个属性,因子基于整形向量实现,这两个属性是:class(),为“factor”,该属性使得因子与常规整形向量有不同行为,另一个属性levels(),定义了因子中允许出现的值。

  1. x <- factor(c("a", "b", "b", "a"))
  2. x
  3. #> [] a b b a
  4. #> Levels: a b
  5. class(x)
  6. #> [] "factor"
  7. levels(x)
  8. #> [] "a" "b"
  9.  
  10. # You can't use values that are not in the levels
  11. x[] <- "c"
  12. #> Warning in `[<-.factor`(`*tmp*`, , value = "c"): invalid factor level, NA
  13. #> generated
  14. x
  15. #> [] a <NA> b a
  16. #> Levels: a b
  17.  
  18. # NB: you can't combine factors
  19. c(factor("a"), factor("b"))
  20. #> []

  当你知道一个变量可能的值时,因子很有用,即使给定数据集中并没有出现所有值。当某些值没有出现,使用因子比使用字符向量显得这种情况更加明显:

  1. sex_char <- c("m", "m", "m")
  2. sex_factor <- factor(sex_char, levels = c("m", "f"))
  3.  
  4. table(sex_char)
  5. #> sex_char
  6. #> m
  7. #>
  8. table(sex_factor)
  9. #> sex_factor
  10. #> m f
  11. #>

  有时候数据直接从文件中读取,你可能觉得某一列应该是数值向量而不是因子,但情况却非如此。这是由列中非数值的值造成的,这种非数值的值通常是缺失值,这些缺失值由特殊方式出现,比如.或者-。为了处理这个情况,需要将因子强制转换为字符向量,然后将字符向量强制转换为双精度向量。(处理完后记得检查缺失值。)当然,最好的方法是找出问题出现的地方并加以修复,在read.csv()中设置na.strings参数是不错的方法。

  1. # Reading in "text" instead of from a file here:
  2. z <- read.csv(text = "value\n12\n1\n.\n9")
  3. typeof(z$value)
  4. #> [] "integer"
  5. as.double(z$value)
  6. #> []
  7. # Oops, that's not right: 3 2 1 4 are the levels of a factor,
  8. # not the values we read in!
  9. class(z$value)
  10. #> [] "factor"
  11. # We can fix it now:
  12. as.double(as.character(z$value))
  13. #> Warning: NAs introduced by coercion
  14. #> [] NA
  15. # Or change how we read it in:
  16. z <- read.csv(text = "value\n12\n1\n.\n9", na.strings=".")
  17. typeof(z$value)
  18. #> [] "integer"
  19. class(z$value)
  20. #> [] "integer"
  21. z$value
  22. #> [] NA
  23. # Perfect! :)

  不幸的是,R中绝大多数加载函数会将字符向量自动转换为因子。这不是最优的,因为这些函数不可能知道所有的因子水平或者最优次序。因此,设置stringsAsFactors = FALSE参数来禁止这种情况,然后根据你对数据的了解,手动的将字符向量转换为因子。有个全局选项,options(stringsAsFactors = FALSE),可以用来控制自动转换为因子的情况,但是我不建议这么做。修改全局选项,可能导致其他代码出现异常(当使用其他包或者使用source()导入代码时),而且会使得代码难以理解,因为修改全局选项会增加代码的数量,而这本来可以由一行代码实现。

  因子看起来(而且经常表现的)像字符向量,但是因子其实是整形向量。将因子作为字符串对待需要非常小心。一些字符串方法(比如gsub()grepl())会将因子强制转换为字符串,而其他方法(比如nchar())会抛出错误,其他一些(比如c())会使用因子背后的整形值。因此,如果你想让因子表现的像字符串一样,通常最好的方法是显示的将因子转化为字符向量。在R的早期版本,因子比字符向量有内存上的优势,但现在情况不同了。

练习

  1. 之前一个说明structure()的代码草稿:
  1. structure(:, comment = "my attribute")
  2. #> []

  但是当你打印结果时,并没有看到comment这个属性。为什么?难道这个属性丢失了,或者comment属性有其他什么特殊的?(思路:使用help)

  2. 当修改因子的水平时会发生什么?

  1. f1 <- factor(letters)
  2. levels(f1) <- rev(levels(f1))

  3.下列代码是干什么的?f2和f3为何与f1不同?

  1. f2 <- rev(factor(letters))
  2.  
  3. f3 <- factor(letters, levels = rev(letters))

矩阵和数组

  在原子向量上添加dim()属性,可以使得它表现的像多维数组。一个特殊的数组是矩阵,矩阵是2维的。矩阵常被作为数学统计工具的一部分。数组要少见一些,但是也值得关注。

  矩阵和数组可以通过matrix()array()创建,或者赋予原子向量dim()属性:

  1. # Two scalar arguments to specify rows and columns
  2. a <- matrix(:, ncol = , nrow = )
  3. # One vector argument to describe all dimensions
  4. b <- array(:, c(, , ))
  5.  
  6. # You can also modify an object in place by setting dim()
  7. c <- :
  8. dim(c) <- c(, )
  9. c
  10. #> [,] [,]
  11. #> [,]
  12. #> [,]
  13. #> [,]
  14. dim(c) <- c(, )
  15. c
  16. #> [,] [,] [,]
  17. #> [,]
  18. #> [,]

  length()names()有高维的概括结果:

  • length()概括了矩阵的nrow()ncol(),对应数组的是dim()
  • names()概括了矩阵的rownames()colnames(),对应数组的是dimnames()dimnames()是一个字符向量的列表。
  1. length(a)
  2. #> []
  3. nrow(a)
  4. #> []
  5. ncol(a)
  6. #> []
  7. rownames(a) <- c("A", "B")
  8. colnames(a) <- c("a", "b", "c")
  9. a
  10. #> a b c
  11. #> A
  12. #> B
  13.  
  14. length(b)
  15. #> []
  16. dim(b)
  17. #> []
  18. dimnames(b) <- list(c("one", "two"), c("a", "b", "c"), c("A", "B"))
  19. b
  20. #> , , A
  21. #>
  22. #> a b c
  23. #> one
  24. #> two
  25. #>
  26. #> , , B
  27. #>
  28. #> a b c
  29. #> one
  30. #> two

  c()概括了矩阵的cbind()rbind(),对应数组的是abind()(由abind包提供)。对矩阵转置可使用t();对数组更加一般化的转置可使用aperm()

  可以使用is.matrix()测试一个对象是否是矩阵,使用is.array()测试一个对象是否是数组,或者查看dim()的长度。使用as.matrix()和as.array()可以很容易的将已有的向量转换为矩阵和数组。

  向量不是唯一的1维数据结构。矩阵可以只有一行或者一列,数组也可以只有1维。它们打印结果可能相似,但是表现不同。不同之处并不是太重要,但是你需要知道存在不同,万一你调用某个函数(tapply()是常见的一个)时得到了奇怪的输出。通常可以使用str()看看有何不同。

  1. str(:) # 1d vector
  2. #> int [:]
  3. str(matrix(:, ncol = )) # column vector
  4. #> int [:, ]
  5. str(matrix(:, nrow = )) # row vector
  6. #> int [, :]
  7. str(array(:, )) # "array" vector
  8. #> int [:(1d)]

  虽然最常见的情况是将原子向量转换为矩阵,维数属性同样可以作用于列表,使得其表现的像列表矩阵或者列表数组:

  1. l <- list(:, "a", TRUE, 1.0)
  2. dim(l) <- c(, )
  3. l
  4. #> [,] [,]
  5. #> [,] Integer, TRUE
  6. #> [,] "a"

  这些是相对难懂的数据结构,但是将对象布局到类似网格的结构时非常有用。比如,当你运行一个时空网格模型,通过将模型存储到3维数组来保存网格结构是很自然的事情。

练习

  1. dim()作用于向量时返回什么?
  2. 如果is.matrix(x)TRUE,那is.array(x)返回什么?
  3. 你如何描述下列代码中的3个对象?这3个对象与1:5有何不同?
  1. x1 <- array(:, c(, , ))
  2. x2 <- array(:, c(, , ))
  3. x3 <- array(:, c(, , ))

数据框

  数据框是R中最常见的数据存储方式,而且如果使用得当(used systematically)会使数据分析变得非常容易。在底层,数据框是一个列表,列表中的元素是长度相等的向量。也就是说数据框是2维数据结构,所以它兼有矩阵和列表的属性。也就是说数据框有names()colnames(),和 rownames()属性,尽管names()colnames()对数据框是同一个事情。对数据框来说,length()得到数据框底层列表的长度,因此length()ncol()结果相同;nrow()得到行的数量。

  正如在subsetting介绍的,对于数据框,你可以像1维数据结构(数据框表现的像列表),或者2维数据结构(数据框表现的像矩阵)一样取子集。

创建

  可以使用data.frame()创建数据框,它以命名的向量作为输入:

  1. df <- data.frame(x = :, y = c("a", "b", "c"))
  2. str(df)
  3. #> 'data.frame': obs. of variables:
  4. #> $ x: int
  5. #> $ y: Factor w/ levels "a","b","c":

  注意data.frame()默认将字符串转换为因子。使用stringAsFactors = FALSE禁止这种情况:

  1. df <- data.frame(
  2. x = :,
  3. y = c("a", "b", "c"),
  4. stringsAsFactors = FALSE)
  5. str(df)
  6. #> 'data.frame': obs. of variables:
  7. #> $ x: int
  8. #> $ y: chr "a" "b" "c"

测试和强制转换

  因为data.frame是S3类,它的类型是底层用来创建它的向量:列表。测试一个对象是否是数据框,使用class(),或者显示使用is.data.frame()

  1. typeof(df)
  2. #> [] "list"
  3. class(df)
  4. #> [] "data.frame"
  5. is.data.frame(df)
  6. #> [] TRUE

  可以使用as.data.frame()将对象强制转换为数据框:

  • 作用于向量会创建一个一列的数据框。
  • 作用于列表会为列表的每个元素创建一个列;如果列表元素的长度不同会抛出错误。
  • 作用于矩阵,得到一个具有相同列数和行数的数据框。

合并数据框

  使用cbind()rbind()合并数据框:

  1. cbind(df, data.frame(z = :))
  2. #> x y z
  3. #> a
  4. #> b
  5. #> c
  6. rbind(df, data.frame(x = , y = "z"))
  7. #> x y
  8. #> a
  9. #> b
  10. #> c
  11. #> z

  当以列方式合并时,数据框的行数必须相同,但是行名称可以不同。当以行方式合并时,数据框的列数和列名称都必须匹配。使用plyr::rbind.fill()组合列不同的情况。

  一个常见的错误是使用cbind()将向量组合为数据框。这不好使因为cbind()会创建一个矩阵,除非cbind()的一个实参已经是数据框了。直接使用data.frame()来将向量合并为数据框

  1. bad <- data.frame(cbind(a = :, b = c("a", "b")))
  2. str(bad)
  3. #> 'data.frame': obs. of variables:
  4. #> $ a: Factor w/ levels "","":
  5. #> $ b: Factor w/ levels "a","b":
  6. good <- data.frame(a = :, b = c("a", "b"),
  7. stringsAsFactors = FALSE)
  8. str(good)
  9. #> 'data.frame': obs. of variables:
  10. #> $ a: int
  11. #> $ b: chr "a" "b"

  cbind()的转换规则很复杂,最好的方式是确保所有的输入有相同的类型。

特殊列

  因为数据框是包含向量的列表,因此数据框的列可能是列表:

  1. df <- data.frame(x = :)
  2. df$y <- list(:, :, :)
  3. df
  4. #> x y
  5. #> ,
  6. #> , ,
  7. #> , , ,

  然而,当列表作为data.frame()的输入时,列表会试图将其中的每个元素转换为一列,因此会失败:

  1. data.frame(x = :, y = list(:, :, :))
  2. #> Error in data.frame(:, :, :, check.names = FALSE, stringsAsFactors = TRUE): arguments imply differing number of rows: , ,

  一种解决方法是使用I()I()使得data.frame()将列表看作一个整体:

  1. dfl <- data.frame(x = :, y = I(list(:, :, :)))
  2. str(dfl)
  3. #> 'data.frame': obs. of variables:
  4. #> $ x: int
  5. #> $ y:List of
  6. #> ..$ : int
  7. #> ..$ : int
  8. #> ..$ : int
  9. #> ..- attr(*, "class")= chr "AsIs"
  10. dfl[, "y"]
  11. #> [[]]
  12. #> []

   I()添加AsIs类作为输入,但通常可以无视。

  相似的,数据框的一列也可以是矩阵或者数组,只要行数匹配即可:

  1. dfm <- data.frame(x = :, y = I(matrix(:, nrow = )))
  2. str(dfm)
  3. #> 'data.frame': obs. of variables:
  4. #> $ x: int
  5. #> $ y: 'AsIs' int [:, :]
  6. dfm[, "y"]
  7. #> [,] [,] [,]
  8. #> [,]

  使用列表和数组作为列需要小心:许多函数作用于数据框时,假设数据框的列是原子向量。

练习

  1. 数据框有哪些属性?
  2. as.matrix()作用于数据框,而且该数据框的列是不同类型的,会发生什么?
  3. 一个数据框可以有0行吗?0列哪?

答案

  1. 向量的3个属性是类型,长度和属性。
  2. 常见的4种原子向量类型是逻辑向量,整形向量,双精度向量(有时称为数值向量),字符向量。2种不常见的类型是复数向量和raw向量。
  3. 属性允许在任何对象上添加任意附加元数据。可以使用attr(x, "y")attr(x, "y") <- value获取和设置一个属性;或者使用attributes()一次性获取和设置所有属性。
  4. 列表的元素可以是任意类型的(甚至列表);原子向量的所有元素必须是同类型的。类似的,矩阵的所有元素必须是同类型的;数据框中的不同列可以是不同类型的。
  5. 通过设置列表的维数得到“列表数组”。可以使用df$x <- matrix()将矩阵作为数据框的一列,或者在创建数据框时使用I(),就像data.frame(x = I(matrix()))

Advanced R之数据结构的更多相关文章

  1. 【R】数据结构

    之前一阵子,在EDX上学习了R语言的一门基础课程,这里做个总结.这门课程主要侧重于R的数据结构的介绍,当然也介绍了它的基本的绘图手段. 工作空间相关 ls() ## character(0) rm(a ...

  2. R语言-数据结构

    1.向量 向量是用来存储数值型.字符型或逻辑性数据的一维数组,用函数c()创建向量 a <- c(1,2,5,6,4) b <- c("one","two&q ...

  3. R语言数据结构

    5. 数据结构 5.1 数据结构简介 (1)向量 一个向量的所有元素必须有相同的类型(模式) (2)列表 列表可以非同质的 列表可按位置索引:lst[[2]] 抽取子列表:lst[c(2,5)] 列表 ...

  4. 第二章 R语言数据结构

    R语言存储数据的结构包括:标量.向量.矩阵.数组.数据框和列表:可以处理的数据类型包括:数值型.字符型.逻辑型.复数型和原生型. 数据结构 向量 向量是用来存储数值型.字符型或逻辑型数据的一维数组.单 ...

  5. R的数据结构

    R语言中的数据结构包括标量.向量.矩阵.数组.列表以及数据框 目录 1 向量 2 矩阵 3 数据框 1 向量 向量是用于存储单一数据类型(数值.字符.逻辑值)的一维数组,示例如下: a <- c ...

  6. Advanced R之词汇表

    转载请注明出处:http://www.cnblogs.com/lizichao/p/4800513.html 词汇表 想要玩得转R,重要的一点是有一个好的工作词汇表.以下是我认为的一个好的词汇表.你不 ...

  7. Advanced R之构造子集

    转发请声明出处:http://www.cnblogs.com/lizichao/p/4794733.html 构造子集 R构造子集的操作功能强大而且速度快.精通构造子集者可以用简洁的方式表达复杂的操作 ...

  8. R语言数据结构二

    上节我们讲到R语言中的基本数据类型,包括数值型,复数型,字符型,逻辑型以及对应的操作和不同数值类型之间的转换.众所周知,R语言的优势在于进行数据挖掘,大数据处理等方面,因此单个的数据并不能满足我们的需 ...

  9. R语言数据结构一

    R是面向对象的语言,它跟其他编程语言的数据类型差不多,有四种,分别为:数值型,复数型,逻辑性和字符型 数值型:即数字,分为整数型和双精度型.数字可以用科学技术法表示,形式为Xe+m,意为x乘10的m次 ...

随机推荐

  1. 简单理解ThreadLocal原理和适用场景

    https://blog.csdn.net/qq_36632687/article/details/79551828?utm_source=blogkpcl2 参考文章: 正确理解ThreadLoca ...

  2. PowerBuilder -- 数据窗口

    获取数据窗口列数 ls_colnum= integer(this.Describe("DataWindow.Column.Count")) 获取数据窗口列名 ls_colName ...

  3. cocos2dx 3.2+ 项目创建与问题总汇

    本文为Cocos2d-x 3.x 全平台(Android,iOS)新手开发配置教程攻略,希望对大家有所帮助.由于这篇文章是面对新手的. 所以有些地方会啰嗦一些,请勿见怪. 假设教程中有错误.欢迎指正. ...

  4. 【转】Android7.0版本以上的手机Eclipse无法打出LogCat

    本来想用Eclipse连下手机看下log的,结果LogCat没打出来任何信息,起初怀疑是我的DDMS有问题,结果连了下我老大的手机,完美打出log,看了下Android系统,老大的是6.0的,我的7. ...

  5. mfc 小程序---在系统菜单中添加菜单项

    1建立一个对话框工程:在dlg类里定义一个菜单指针m_pMenu,在对话框OnInitDialog函数里添加代码: m_pMenu=GetSystemMenu(FALSE);//获取系统菜单的指针 m ...

  6. iOS 10 的杂碎资料

    兼容iOS 10 资料整理笔记   1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大 ...

  7. 2017-2018-1 20179209《Linux内核原理与分析》第二周作业

    本周课业主要通过分析汇编代码执行情况掌握栈的变化.本人本科时期学过intel 80X86汇编语言,所以有一定基础:在Linux中32位AT&T风格的汇编稍微熟悉就可以明白.所以我学习的重点放在 ...

  8. [持续集成]Jenkins 自动化部署 Maven 工程

    一.Jenkins 持续部署原理图 基础服务: 1 SVN 服务 SVN是Subversion的简称,是一个开放源代码的版本控制系统.说得简单一点SVN就是用于多个人共同开发同一个项目,共用资源的目的 ...

  9. SAP RFC 的介绍

    第一部分 RFC技术 什么是RFC? RFC是SAP系统和其他(SAP或非SAP)系统间的一个重要而常用的双向接口技术,也被视为SAP与外部通信的基本协议.简单地说,RFC过程就是系统调用当前系统外的 ...

  10. Machine Learning No.8: Clusting

    1. K-means algorithm 2. K-means optimization objective 3. Random initialization