7

我试图弄清楚为什么rbind在加入没有名称的 data.frames 时该功能无法按预期工作。这是我的测试:

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,我可以将错误识别为在函数的此if语句部分期间发生rbind.data.frame

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

(这里的代码在线版本:http ://svn.r-project.org/R/trunk/src/library/base/R/dataframe.R开始于:“ ### 这里是 rbind 和 cbind 的方法。 ")

从单步执行程序来看,此时pi似乎没有设置 的值,因此程序尝试索引内置常量pilikepi[[3]]并出错。

据我所知,内部pi对象似乎没有设置,因为前面的行clabs已被初始化为NULL

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

我很纠结,试图弄清楚这一点,但会随着它的组合而更新。

4

1 回答 1

6

因为unname()& 明确地将 NA 指定为列标题不是相同的操作。当列名都是 NA 时,anrbind()是可能的。由于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两个数据帧可以“rbound”,但没有任何列标题的两个数据帧(使用 实现unname())不能。

于 2012-11-28T07:57:18.973 回答