Hello everyone, A recent (in 2.5 I suspect) change in R is giving me trouble. I want to apply a function (tolower) to all the columns of a data.frame and get a data.frame in return. Currently, on a data.frame, both apply (for arrays) and lapply (for lists) work, but each returns its native class (resp. matrix and list): apply(mydat,2,tolower) # gives a matrix lapply(mydat,tolower) # gives a list and sapply(mydat,tolower) # gives a matrix If I remember well, apply did not used to work on data.frames and lapply returned a data.frame when it was provided with one, with the same properties (columns classes etc). At least this is what my code written with R 2.4.* suggests. The solution would be: as.data.frame(apply(mydat,2,tolower)) or as.data.frame(lapply(mydat,tolower)) But this does not keep columns attributes (all columns are reinterpreted, for example strings are converted to factors etc). For my particular use stringsAsFactors=FALSE does what I need, but I am wondering wether there is a more general solution to apply a function on all elements of a data.frame and get a similar data.frame in return. Indeed data.frames are probably the most common object in R and applying a function to each of its columns/variables appears to me as something one would want to do quite often. Thank you in advance. JiHO --- http://jo.irisson.free.fr/
On Mon, 30 Jul 2007, jiho wrote:> Hello everyone, > > A recent (in 2.5 I suspect) change in R is giving me trouble. I want > to apply a function (tolower) to all the columns of a data.frame and > get a data.frame in return. > Currently, on a data.frame, both apply (for arrays) and lapply (for > lists) work, but each returns its native class (resp. matrix and list): > > apply(mydat,2,tolower) # gives a matrix > lapply(mydat,tolower) # gives a list > and > sapply(mydat,tolower) # gives a matrixwhich is exactly what R 2.0.0 did, so no recent(ish) change at all.> If I remember well, apply did not used to work on data.frames and > lapply returned a data.frame when it was provided with one, with the > same properties (columns classes etc). At least this is what my code > written with R 2.4.* suggests.apply has coerced data frames for many years and lapply always returned a list. The solution has always been mydat[] <- lapply(mydat,tolower)> The solution would be: > as.data.frame(apply(mydat,2,tolower)) > or > as.data.frame(lapply(mydat,tolower)) > > But this does not keep columns attributes (all columns are > reinterpreted, for example strings are converted to factors etc). For > my particular use stringsAsFactors=FALSE does what I need, but I am > wondering wether there is a more general solution to apply a function > on all elements of a data.frame and get a similar data.frame in > return. Indeed data.frames are probably the most common object in R > and applying a function to each of its columns/variables appears to > me as something one would want to do quite often. > > Thank you in advance. > > JiHO > --- > http://jo.irisson.free.fr/ > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >-- Brian D. Ripley, ripley at 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
On 2007-July-30 , at 12:20 , Prof Brian Ripley wrote:> On Mon, 30 Jul 2007, jiho wrote: >> A recent (in 2.5 I suspect) change in R is giving me trouble. I want >> to apply a function (tolower) to all the columns of a data.frame and >> get a data.frame in return. >> Currently, on a data.frame, both apply (for arrays) and lapply (for >> lists) work, but each returns its native class (resp. matrix and >> list): >> >> apply(mydat,2,tolower) # gives a matrix >> lapply(mydat,tolower) # gives a list >> and >> sapply(mydat,tolower) # gives a matrix > > which is exactly what R 2.0.0 did, so no recent(ish) change at all. > >> If I remember well, apply did not used to work on data.frames and >> lapply returned a data.frame when it was provided with one, with the >> same properties (columns classes etc). At least this is what my code >> written with R 2.4.* suggests. > > apply has coerced data frames for many years and lapply always > returned a list. The solution has always been > > mydat[] <- lapply(mydat,tolower)sorry about that, my previous code was misleading and indeed your code above does exactly what I need. I should have tested this a bit further before posting. I was just afraid to install two different R versions I guess. thank you again. JiHO --- http://jo.irisson.free.fr/