创建带有列名的空数据框。

16

我想创建一个包含两列并且行数未知的空数据框。我想指定列的名称。我运行了以下命令:

dat <- data.frame("id"=numeric(),"nobs"=numeric())  

我可以通过运行来测试结果

> str(dat)
'data.frame':   0 obs. of  2 variables:
 $ id  : num 
 $ nobs: num   

但是当我使用以下命令中的rbind将数据插入到这个数据帧中时,列名也会更改。

  for (i in id) {
    nobs = nrow(na.omit(read.csv(files_list[i])))
    dat = rbind(dat, c(i,nobs))
  } 

for循环结束后dat的值为:

dat
  X3 X243
1  3  243

并且 str 命令显示如下内容

str(dat)

'data.frame':   1 obs. of  2 variables:
 $ X3  : num 3
 $ X243: num 243

有人能告诉我为什么数据框中的列名会改变吗?

编辑:

我的懒惰解决方案是在将数据绑定到我的数据框后运行以下命令:

names(dat)[1] = "id"
names(dat)[2] = "nobs"

更简单的例子:rbind(dat,c(3,243)) - Ben Bolker
我很惊讶将原子向量“c(i,nobs)”绑定到数据框时并没有抛出错误。本以为需要“list(id=i,nobs=nobs)”。 - IRTFM
有人正在上Coursera课程...我自己也遇到了麻烦,并且构建了懒惰的解决方案!你后来发现解决方案了吗? - Parseltongue
4个回答

10

有趣的是,rbind.data.frame函数会抛弃所有行数为零的值。这实际上发生在以下这一行:

allargs <- allargs[nr > 0L]

因此,传递一个没有行的数据框实际上就像什么都没有传递一样。这是另一个很好的例子,说明尝试逐行构建数据框几乎总是一个坏主意。最好先构建向量,然后在完成时将它们组合成数据框。


从源代码的注释中可以看出:"删除任何零行数据框,因为它们可能没有正确的列类型(例如NULL)"。自2007年以来就一直是这样。也许这不是最直观的默认行为,但我通常认为阻止人们以这种方式使用数据框(即逐行构建它们)是一个好主意。 - MrFlick
@MrFlick,那么我该如何解决这个问题呢?在我的情况下,我不知道数据框的行数,因为我是使用for循环从另一个数据框中读取数据。 - Khurram Majeed
@KhurramMajeed。嗯,不要使用循环是首选方案。通常最好的策略是逐列构建。我不知道你具体在做什么,但很可能有更符合R语言风格的方法来完成它。 - MrFlick
一种懒惰的解决方案是在循环后通过使用 names(dat)[1] = "id"names(dat)[2] = "obs" 重命名列名。 - Khurram Majeed
4
使用for循环将数据读入一个数据帧列表中,然后使用do.call(rbind,list_of_frames)将它们合并成一个大的数据框。 - Ben Bolker

2
dat = data.frame(col1=numeric(), col2=numeric())  

...loop
    dat[, dim(dat)[1] + 1] = c(324, 234) 

这会保留列名。

1
你应该尝试在rbind()函数内指定列名:
dat = rbind(dat, data.frame("id" = i, "nobs" = nobs))

0
我建议您更改将数据附加到数据框的方法。由于rbind似乎会删除列名,所以建议您使用索引位置进行替换。
dat <- data.frame("id"=numeric(),"nobs"=numeric())  

for (i in id) {
   dat[i,] <- nrow(na.omit(read.csv(files_list[i])))

 } 

顺便提一下,默认的数据框创建会将所有字符串转换为因子,但这里没有问题,因为您的所有数据格式都是数值型的。但如果您有一个字符向量,您可能想要关闭默认的stringsAsFactors=FALSE选项,以追加字符列表。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接