代码之家  ›  专栏  ›  技术社区  ›  T K

将值作为新行添加到数据帧,但保留所有其他列NA

  •  1
  • T K  · 技术社区  · 2 年前

    以下是我的示例数据集:

    mydata = data.frame (ID =c(1,2,3,4,5),
    subject = c("His","Geo","Geo","His","Geo"),
    age = c(21,24,26,23,26))
    
    

    我想在顶部添加一行。我希望在ID栏中显示“学校1”,而所有其他栏保持空白。以下是我正在寻找的内容:

    mydata = data.frame (ID =c("School 1",1,2,3,4,5),
    subject = c(NA,"His","Geo","Geo","His","Geo"),
    age = c(NA,21,24,26,23,26))
    

    我尝试了以下操作,但最终会在所有列中填充值:

    mydata <- rbind(c("School 1"), mydata)
    
    

    我知道下面的代码会得到我想要的,但我想避免列出NA,因为我的数据集有很多列

    mydata <- rbind(c("School 1", NA,NA), mydata)
    
    

    感谢您的帮助!

    2 回复  |  直到 2 年前
        1
  •  1
  •   PaulS    2 年前

    一个可能的解决方案,基于 dplyr 。我们首先需要转换 ID 从…起 numeric character .

    library(dplyr)
    
    mydata %>% 
      mutate(ID = as.character(ID)) %>% 
      bind_rows(list(ID = "School 1"), .)
    
    #> # A tibble: 6 × 3
    #>   ID       subject   age
    #>   <chr>    <chr>   <dbl>
    #> 1 School 1 <NA>       NA
    #> 2 1        His        21
    #> 3 2        Geo        24
    #> 4 3        Geo        26
    #> 5 4        His        23
    #> 6 5        Geo        26
    
        2
  •  0
  •   jay.sf    2 年前

    使用 `length<-` ,用填充不存在的元素 NA 在指定的总长度以内,可以创建一个长度正好为 ncol(mydata) ,带有第一个元素 'School 1' 然后 rbind .

    rbind(`length<-`("School 1", ncol(mydata)), mydata)
    #         ID subject age
    # 1 School 1    <NA>  NA
    # 2        1     His  21
    # 3        2     Geo  24
    # 4        3     Geo  26
    # 5        4     His  23
    # 6        5     Geo  26
    

    解释

    也许值得思考数据框架的概念,以便更好地理解OP的问题。事实上,这是一个修改 list ,

    typeof(mydata)
    # [1] "list"
    

    并且由长度相等的向量组成,当我们 unclass

    unclass(mydata)
    # $ID
    # [1] 1 2 3 4 5
    # 
    # $subject
    # [1] "His" "Geo" "Geo" "His" "Geo"
    # 
    # $age
    # [1] 21 24 26 23 26
    # 
    # attr(,"row.names")
    # [1] 1 2 3 4 5
    

    我们可以容易地将其他元素添加到列表中,

    c(mydata, foo='something')
    # $ID
    # [1] 1 2 3 4 5
    # 
    # $subject
    # [1] "His" "Geo" "Geo" "His" "Geo"
    # 
    # $age
    # [1] 21 24 26 23 26
    # 
    # $foo
    # [1] "something"
    

    但是用它制作一个数据帧,值会得到 recycled ,如果没有提供其他内容(这实际上非常有用)。

    as.data.frame(c(mydata, foo='something'))
    #   ID subject age       foo
    # 1  1     His  21 something
    # 2  2     Geo  24 something
    # 3  3     Geo  26 something
    # 4  4     His  23 something
    # 5  5     Geo  26 something
    

    这与完全相同 cbind .

    cbind(mydata, foo='something')
    #   ID subject age       foo
    # 1  1     His  21 something
    # 2  2     Geo  24 something
    # 3  3     Geo  26 something
    # 4  4     His  23 something
    # 5  5     Geo  26 something
    

    如果我们提供一个适当长度的矢量(即 到数据帧),R没有理由回收。

    as.data.frame(c(mydata, list(foo=c('something', rep(NA, 4)))))
    #   ID subject age       foo
    # 1  1     His  21 something
    # 2  2     Geo  24      <NA>
    # 3  3     Geo  26      <NA>
    # 4  4     His  23      <NA>
    # 5  5     Geo  26      <NA>
    
    cbind(mydata, foo=c('something', rep(NA, 4)))
    #   ID subject age       foo
    # 1  1     His  21 something
    # 2  2     Geo  24      <NA>
    # 3  3     Geo  26      <NA>
    # 4  4     His  23      <NA>
    # 5  5     Geo  26      <NA>
    

    正在添加 略有不同。正如我们在 松开 我们可以想象,我们需要 append 在所需的位置上对每个单个矢量进行一些运算。可以说,这违背了初衷。显然,这也是计算成本更高,因此速度慢得多。

    as.data.frame(Map(append, mydata, values=c('something', rep(NA, 2)), after=0))
    #          ID subject  age
    # 1 something    <NA> <NA>
    # 2         1     His   21
    # 3         2     Geo   24
    # 4         3     Geo   26
    # 5         4     His   23
    # 6         5     Geo   26
    

    注意,要附加比 ncol 也将导致OP所经历的回收。

    as.data.frame(Map(append, mydata, values='something', after=0))
    #          ID   subject       age
    # 1 something something something
    # 2         1       His        21
    # 3         2       Geo        24
    # 4         3       Geo        26
    # 5         4       His        23
    # 6         5       Geo        26
    

    R rbind 已经在C语言中关心这一点了,这很快,我们不需要 Map 胜过一切;

    rbind(c("something", NA, NA), mydata)
    

    以避免无休止地键入 NA 因此,我们可以使用所提出的解决方案:

    rbind(`length<-`("School 1", ncol(mydata)), mydata)
    #          ID subject  age
    # 1 something    <NA> <NA>
    # 2         1     His   21
    # 3         2     Geo   24
    # 4         3     Geo   26
    # 5         4     His   23
    # 6         5     Geo   26