From ripley at stats.ox.ac.uk  Thu Jan  8 09:36:45 2004
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Thu Jan  8 09:35:18 2004
Subject: [Rd] problem assigning an array to a variable in a data frame
In-Reply-To: <5.1.0.14.2.20040107172840.01fef4b0@127.0.0.1>
Message-ID: <Pine.LNX.4.44.0401080757160.9950-100000@gannet.stats>

The problem is not in $ but in printing the resulting object (try
traceback()).  You assigned a column which is a one-dimensional array:

> unlist(sapply(sample20, class))
  school1   school2       ses   mathach   meanses 
"ordered"  "factor" "numeric" "numeric"   "array" 

I presume you did not actually intend to do this?

The `problem' is in the use of tapply, which does something different here
from its S counterpart: in R you need to surround its result by drop().  
In R <= 1.8.0 subsetting a 1-d array dropped the dimensions, which was a
bug, and you were saved by a fortuitous subsetting.

But what $ does in R is compatible with S:

X <- data.frame(x=1:10)
y <- array(1:10, dim=10)
X$y <- y
sapply(X, class)

for which both give integer, array.

However, R's print method is deficient and so the error message is in
precisely the right place.  (S does have an array method for
as.data.frame, and since S4 classes were introduced into R, R needs one.)

Brian

On Wed, 7 Jan 2004, John Fox wrote:

> Dear r-devel list members,
> 
> Dirk Eddelbuettel brought the following problem to my attention. The code 
> is abstracted from the appendix on mixed models from my R and S-PLUS Companion:
> 
>  > set.seed(12345)  # for reproducibility
>  > library(nlme)
> Loading required package: lattice
>  > data(MathAchieve)
>  > data(MathAchSchool)
>  > attach(MathAchieve)
>  > mses <- tapply(SES, School, mean)
>  > detach(MathAchieve)
>  > Bryk <- as.data.frame(MathAchieve[, c("School", "SES", "MathAch")])
>  > names(Bryk) <- c("school", "ses", "mathach")
>  > sample20 <- sort(sample(7185, 20))
>  > Bryk$meanses <- mses[as.character(Bryk$school)]
>  > Bryk[sample20,]
> Error in as.data.frame.default(x[[i]], optional = TRUE) :
>          can't coerce array into a data.frame
>  >
> 
> This is with R 1.8.1 under Windows 2000. The same code works fine with R 
> 1.8.0. As Dirk discovered, the problem disappears if the assignment
> 
> Bryk$meanses <- mses[as.character(Bryk$school)]
> 
> is changed to
> 
> Bryk$meanses <- as.vector(mses[as.character(Bryk$school)])
> 
> It seems to me that it if $ doesn't want to coerce the array 
> mses[as.character(Bryk$school)] to a vector (as I guess was previously the 
> case), 

Don't guess, check!

> then the error should have been produced at that point.
> 
> Thanks,
>   John
> -----------------------------------------------------
> John Fox
> Department of Sociology
> McMaster University
> Hamilton, Ontario, Canada L8S 4M4
> email: jfox@mcmaster.ca
> phone: 905-525-9140x23604
> web: www.socsci.mcmaster.ca/jfox
> 
> ______________________________________________
> R-devel@stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-devel
> 
> 

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595


[Rd] problem assigning an array to a variable in a data frame
Prof Brian Ripley