2012-11-28 42 views
6

我想弄清楚为什么rbind函数不符合预期的时候加入data.frames没有名称。 这里是我的测试:rbind data.frames without names

test <- data.frame(
      id=rep(c("a","b"),each=3), 
      time=rep(1:3,2), 
      black=1:6, 
      white=1:6, 
      stringsAsFactors=FALSE 
      ) 

# take some subsets with different names 
pt1 <- test[,c(1,2,3)] 
pt2 <- test[,c(1,2,4)] 

# method 1 - rename to same names - works 
names(pt2) <- names(pt1) 
rbind(pt1,pt2) 

# method 2 - works - even with duplicate names 
names(pt1) <- letters[c(1,1,1)] 
names(pt2) <- letters[c(1,1,1)] 
rbind(pt1,pt2) 

# method 3 - works - with a vector of NA's as names 
names(pt1) <- rep(NA,ncol(pt1)) 
names(pt2) <- rep(NA,ncol(pt2)) 
rbind(pt1,pt2) 

# method 4 - but... does not work without names at all? 
pt1 <- unname(pt1) 
pt2 <- unname(pt2) 
rbind(pt1,pt2) 

这对我来说似乎有点奇怪。我错过了一个很好的理由,为什么这不应该开箱即用?

编辑,了解更多信息

使用@ JoshO'Brien的建议,debug,我可以识别错误的rbind.data.frame功能

if (is.null(pi) || is.na(jj <- pi[[j]])) 

(网络版的这一if声明部分中发生代码在这里:http://svn.r-project.org/R/trunk/src/library/base/R/dataframe.R开始于:“###这里是rbind和cbind的方法”)

从单步执行程序开始,pi的值似乎并未设置在此位置,因此程序会尝试索引内置常量pi,如pi[[3]]和错误输出。

从我自己看着办,内部pi对象不会出现设置由于这种早期行,其中clabs已被初始化为NULL

if (is.null(clabs)) clabs <- names(xi) else { #pi gets set here 

我在纠结试图弄清楚这但是会在更新时一起更新。

+3

查看'rbind.data.frame'的代码**其中大多数**涉及检查和匹配列名和行名。您可以执行'debug(rbind.data.frame)',然后逐步执行方法4以确定错误发生的位置。 –

+0

@ JoshO'Brien - 已更新以提供更多信息。我在解释代码方面并不擅长,并且正在努力,但也许这对其他人来说是显而易见的。 – thelatemail

回答

5

因为unname() &显式指定NA作为列标题不是相同的操作。当列名全部是NA时,则可以使用rbind()。由于rbind()采用数据帧的名称/姓名,因此结果不匹配&,因此rbind()失败。

下面是一些代码,以帮助明白我的意思:

> c1 <- c(1,2,3) 
> c2 <- c('A','B','C') 
> df1 <- data.frame(c1,c2) 
> df1 
    c1 c2 
1 1 A 
2 2 B 
3 3 C 
> df2 <- data.frame(c1,c2) # df1 & df2 are identical 
> 
> #Let's perform unname on one data frame & 
> #replacement with NA on the other 
> 
> unname(df1) 
    NA NA 
1 1 A 
2 2 B 
3 3 C 
> tem1 <- names(unname(df1)) 
> tem1 
NULL 
> 
> #Please note above that the column headers though showing as NA are null 
> 
> names(df2) <- rep(NA,ncol(df2)) 
> df2 
    NA NA 
1 1 A 
2 2 B 
3 3 C 
> tem2 <- names(df2) 
> tem2 
[1] NA NA 
> 
> #Though unname(df1) & df2 look identical, they aren't 
> #Also note difference in tem1 & tem2 
> 
> identical(unname(df1),df2) 
[1] FALSE 
> 

我希望这有助于。每个名称都显示为NA,但这两个操作是不同的。 因此,将其列标题替换为NA的2个数据帧可以是“rbound”,但是没有任何列标题的2个数据帧(使用unname()实现)不能。

+2

这是很好的信息,我有+ 1ed。虽然我可以看到'NA'和'unname' data.frames有不同的'names()',但我仍然认为如果r能够处理'names()''''''''''这些都是“NA”。 – thelatemail