Bug 15362 - Wishlist: enable simultaneously adding rows and columns by '[<-.data.frame'
Summary: Wishlist: enable simultaneously adding rows and columns by '[<-.data.frame'
Status: NEW
Alias: None
Product: R
Classification: Unclassified
Component: Wishlist (show other bugs)
Version: R 3.0.0
Hardware: ix86 (32-bit) Windows 32-bit
: P5 enhancement
Assignee: R-core
URL:
Depends on:
Blocks:
 
Reported: 2013-06-26 12:14 UTC by Suharto Anggono
Modified: 2013-11-03 11:54 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Suharto Anggono 2013-06-26 12:14:02 UTC
I have sent a message on this to R-devel mailing list: https://stat.ethz.ch/pipermail/r-devel/2013-February/065935.html. Here I reproduce the message.

=========

I saw the following in R help page "Extract.data.frame".

     The replacement methods can be used to add whole column(s) by
     specifying non-existent column(s), in which case the column(s) are
     added at the right-hand edge of the data frame and numerical
     indices must be contiguous to existing indices.  On the other
     hand, rows can be added at any row after the current last row, and
     the columns will be in-filled with missing values.


So, I tried something like this.

> x <- data.frame(a=1, s=1)
> y <- data.frame(a=1, r=8, e=9)
> z <- x
> z[2, c("a","r","e")] <- y
Error in `*tmp*`[[j]] : recursive indexing failed at level 2


Using debug("[<-.data.frame") revealed that execution stopped at this line.

                  length(x[[j]]) <- nrows


From stepping by debug("[<-.data.frame"), I saw that '[<-.data.frame' actually did well before the failing line. In the failing line, it looks like 'jj' is meant instead of 'j'.


In the code of function '[<-.data.frame', near the end, it looks like 'j' needs to be replaced with 'jj' in the lines marked by # below.

    if (has.i)
        for (jjj in seq_len(p)) {
            jj <- jseq[jjj]
            vjj <- value[[jvseq[[jjj]]]]
            if (jj <= nvars) {
                ...
            }
            else {
                x[[jj]] <- vjj[FALSE]
                if (length(dim(vjj)) == 2L) {
                  length(x[[j]]) <- nrows * ncol(vjj)  #
                  dim(x[[j]]) <- c(nrows, ncol(vjj))  #
                  x[[jj]][iseq, ] <- vjj
                }
                else {
                  length(x[[j]]) <- nrows  #
                  x[[jj]][iseq] <- vjj
                }
            }
        }
    else ...


After doing fix("[<-.data.frame") by replacing appropriate 'j' with 'jj', it works.

> fix("[<-.data.frame")
> x <- data.frame(a=1, s=1)
> y <- data.frame(a=1, r=8, e=9)
> z <- x
> z[2, c("a","r","e")] <- y
> z
  a  s  r  e
1 1  1 NA NA
2 1 NA  8  9


> sessionInfo()
R version 2.15.2 (2012-10-26)
Platform: i386-w64-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] tools_2.15.2

=========

I report this here because I still see the same failure with R 3.0.1.

As maybe apparent from my example in the message, my use case is to append a data frame to an existing data frame, where the new data frame has columns that are not present in the old data frame.

I see that function '[<-.data.frame' is not meant to exclude this case. So, I hope that '[<-.data.frame' can be fixed to make this work.
Comment 1 Suharto Anggono 2013-11-03 11:54:59 UTC
This case works.

> x <- data.frame(a=1, s=1)
> y <- data.frame(r=8)
> z <- x
> z[2, "r"] <- y
> z
   a  s  r
1  1  1 NA
2 NA NA  8
> sessionInfo()
R version 3.0.2 (2013-09-25)
Platform: i386-w64-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base