我已经使用 R 很长时间了,所以我不能说“嗨,我是新手,给我解释一下”。但这就是我想问的,因为我不时遇到这个问题,每次我不解决它并做其他事情时。但今天我很好奇地问。

我将数据框视为列的集合,每列的长度都相同。然而,我知道这是错误的。这是错误的,因为可以在数据框中插入矩阵、多列元素。当我不小心这样做时,我最终会得到一个不会打印到屏幕上的东西。有

  • R“head”所说的和它真正拥有的之间看似不一致的列名,以及
  • 我找不到一个明确的方法来询问数据框“你是一个普通的,每个可变数据框一列”,或者“你是否有一些令人沮丧的内部结构,让生活变得困难”?

  • 如果你这样做,你就会明白我的意思。运行
     example(predict.lm)
    

    它运行 predict 方法并生成一个名为 pt 的输出矩阵。

    然后更改他们示例的最后一步,而不是将矩阵输出作为独立的,将其添加到名为 npk 的数据框中
    npk$predict <- predict(npk.aov, type = "terms")
    

    之后,什么是npk?它仍然是一个数据框吗?是的
    > is.data.frame(npk)
      [1] TRUE
    

    嗯,注意 head 是如何报告列名的:
    > head(npk)
      block N P K yield predict.block  predict.N  predict.P
    1     1 0 1 1  49.5    -0.8500000 -4.9250000  0.2083333
    2     1 1 1 0  62.8    -0.8500000  4.9250000  0.2083333
    3     1 0 0 0  46.8    -0.8500000 -4.9250000 -0.2083333
    4     1 1 0 1  57.0    -0.8500000  4.9250000 -0.2083333
    5     2 1 0 0  59.8     2.5750000  4.9250000 -0.2083333
    6     2 1 1 1  58.5     2.5750000  4.9250000  0.2083333
     predict.K predict.N:P predict.N:K predict.P:K
    1 -0.9583333   0.9416667   1.1750000   0.4250000
    2  0.9583333  -2.8250000   1.1750000  -0.1416667
    3  0.9583333   0.9416667   1.1750000  -0.1416667
    4 -0.9583333   0.9416667  -3.5250000  -0.1416667
    5  0.9583333   0.9416667   1.1750000  -0.1416667
    6 -0.9583333  -2.8250000  -3.5250000   0.4250000
      predict.N:P:K
    1     0.0000000
    2     0.0000000
    3     0.0000000
    4     0.0000000
    5     0.0000000
    6     0.0000000
    

    这使它看起来好像有名为“predict.block”或“predict.P”的列,但实际上没有:
    > colnames(npk)
    [1] "block"   "N"       "P"       "K"       "yield"
    [6] "predict"
    

    函数“colnames”更适合命名为“column_or_whatever_else_we_find_here”。

    你一无所获
    > npk$predict.P
    NULL
    

    要访问预测中的那些“列”,您必须知道结构并以矩阵方式询问:
    > npk$predict[ , "P"]
             1          2          3          4          5
     0.2083333  0.2083333 -0.2083333 -0.2083333 -0.2083333
             6          7          8          9         10
     0.2083333 -0.2083333  0.2083333  0.2083333  0.2083333
            11         12         13         14         15
    -0.2083333 -0.2083333 -0.2083333  0.2083333 -0.2083333
            16         17         18         19         20
     0.2083333  0.2083333 -0.2083333 -0.2083333  0.2083333
            21         22         23         24
    -0.2083333  0.2083333  0.2083333 -0.2083333
    

    我只是选择这个例子来展示当我和学生将非列事物附加到数据框时经常意外发生的事情。

    加入 npk 和预测输出的正确方法是合并,我也明白
    > npk.new <- merge(npk, pt, by = "row.names",
                       suffixes = c("", ".predict"))
    > colnames(npk.new)
     [1] "Row.names"     "block"         "N"
     [4] "P"             "K"             "yield"
     [7] "block.predict" "N.predict"     "P.predict"
     [10] "K.predict"     "N:P"           "N:K"
     [13] "P:K"           "N:P:K"
    

    然而,随着生活的发展,有时我们会从一个函数中得到一个矩阵,当我们认为只有一列时,我们不小心最终得到了“数据框内的矩阵”这种结构。

    大多数情况下,我想问的是“你是否也注意到了这一点,它是否像让我一样让你感到沮丧?”但我知道这不是 build 性的。这里有更多 build 性的问题要问。

    如果给您一个数据框,那么了解其中的所有“列”是否都是单列的最直接途径是什么。我试过很明显的,比如:
    > sapply(npk, is.atomic)
      block       N       P       K   yield predict
      TRUE    TRUE    TRUE    TRUE    TRUE    TRUE
    > sapply(npk, is.vector)
      block       N       P       K   yield predict
      FALSE   FALSE   FALSE   FALSE    TRUE   FALSE
    

    到目前为止,我知道我可以询问数据框中的元素是否是矩阵
    > sapply(npk, is.matrix)
      block       N       P       K   yield predict
      FALSE   FALSE   FALSE   FALSE   FALSE    TRUE
    

    因此,我可以编写一个函数,询问每一列“您是矩阵吗”,您是“数据框”还是“数组”。但它似乎,嗯,太乏味了。

    最佳答案

    你也许可以定义

    is.simple <- function(x) {is.vector(x) | is.factor(x)}
    
    sapply(npk, is.simple)
    

    或者可能
    no.dims <- function(x) {is.null(dim(x))}
    sapply(npk, no.dims)
    

    取决于你到底在寻找什么。

    将列添加到 npk 会更安全
    npk <- cbind(npk, predict = predict(npk.aov, type = "terms"))
    

    如果您不确定所涉及的数据类型。直接赋值更危险。

    关于r - 元素不是单列的数据框,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38902880/

    10-12 18:00
    查看更多