[Rd] ftable <-> data.frame etc {was "justify hard coded in format.ftable"}
Gabor Grothendieck
ggrothend|eck @end|ng |rom gm@||@com
Fri May 15 19:58:09 CEST 2020
That's not the problem. The problem is that if you have
ft <- ftable(UCBAdmissions, row.vars = 3:2)
ft
## Admit Admitted Rejected
## Dept Gender
## A Male 512 313
## Female 89 19
## B Male 353 207
## Female 17 8
## C Male 120 205
## ... etc ...
then as.data.frame(ft) gives a deconstructed 24x4 data.frame
like this:
as.data.frame(ft)
## Dept Gender Admit Freq
## 1 A Male Admitted 512
## 2 B Male Admitted 353
## 3 C Male Admitted 120
## 4 D Male Admitted 138
## ... etc ...
which is fine but it does not address the problem here. The
problem here is that we want a a usable data.frame
having columns that correspond to ft. We want this 12x4
data.frame:
## Dept Gender Admitted Rejected
## 1 A Male 512 313
## 2 A Female 89 19
## 3 B Male 353 207
## 4 B Female 17 8
## ... etc ...
The links I provided already pointed to the code below which
someone posted on SO and solves the problem but I would
have thought this would be easy to do in base R and natural
to provide.
ftable2df <- function(mydata) {
ifelse(class(mydata) == "ftable",
mydata <- mydata, mydata <- ftable(mydata))
dfrows <- rev(expand.grid(rev(attr(mydata, "row.vars"))))
dfcols <- as.data.frame.matrix(mydata)
names(dfcols) <- do.call(
paste, c(rev(expand.grid(rev(attr(mydata, "col.vars")))), sep = "_"))
cbind(dfrows, dfcols)
}
ftable2df(ft)
## Dept Gender Admitted Rejected
## 1 A Male 512 313
## 2 A Female 89 19
## 3 B Male 353 207
## 4 B Female 17 8
## ... etc ...
Fri, May 15, 2020 at 12:25 PM Martin Maechler
<maechler using stat.math.ethz.ch> wrote:
>
> >>>>> Gabor Grothendieck
> >>>>> on Thu, 14 May 2020 06:56:06 -0400 writes:
>
> > If you are looking at ftable could you also consider adding
> > a way to convert an ftable into a usable data.frame such as
> > the ftable2df function defined here:
>
> > https://stackoverflow.com/questions/11141406/reshaping-an-array-to-data-frame/11143126#11143126
>
> > and there is an example of using it here:
>
> > https://stackoverflow.com/questions/61333663/manipulating-an-array-into-a-data-frame-in-base-r/61334756#61334756
>
> > Being able to move back and forth between various base class representations
> > seems like something that would be natural to provide.
>
> Sure!
>
> But there is already an as.data.frame() method for "ftable",
> {and I would not want the if(! .. ftable) ftable(x) part anyway.
>
> What I think many useRs / programmeRs very often forget about
> is more-than-2-dimensional arrays {which *are* at the beginning
> of that SO question} and that these are often by far the most
> efficient data structure (rather than the corresponding data frames).
>
> and even less people forget that a "table" in base R is just a
> special case of a 1-D, 2-D, 3-D, .... array.
> (Semantically a special case: "array" with non-negative integer content
>
> I'd claim that everything you here ("move back and forth between
> ...") is already there in the "ftable" implementation in stats,
> notably in the source file src/library/stats/R/ftable.R
> -> https://svn.r-project.org/R/trunk/src/library/stats/R/ftable.R
>
> The problem may be in
>
> 1) too sparse documentation about the close relations
> "ftable" <-> "array" <-> "table" <-> "data.frame"
>
> 2) people not thinking often enough about more-than-2D-arrays and the
> special corresponding class "table" in R.
>
> To start with one:
>
> > str(UCBAdmissions)
> 'table' num [1:2, 1:2, 1:6] 512 313 89 19 353 207 17 8 120 205 ...
> - attr(*, "dimnames")=List of 3
> ..$ Admit : chr [1:2] "Admitted" "Rejected"
> ..$ Gender: chr [1:2] "Male" "Female"
> ..$ Dept : chr [1:6] "A" "B" "C" "D" ...
> >
>
> and look at the *examples* in the help files and the S3 methods
>
> methods(class = "ftable")
> [1] as.data.frame as.matrix as.table format head print
> [7] tail
> see '?methods' for accessing help and source code
> > methods(class = "table")
> [1] [ aperm as.data.frame Axis coerce initialize
> [7] lines plot points print show slotsFromS3
> [13] summary tail
> see '?methods' for accessing help and source code
> >
>
> ... need to close now, there's more to be said ...
>
>
>
> > On Thu, May 14, 2020 at 5:32 AM Martin Maechler
> > <maechler using stat.math.ethz.ch> wrote:
> >>
> >> >>>>> SOEIRO Thomas
> >> >>>>> on Wed, 13 May 2020 20:27:15 +0000 writes:
> >>
> >> > Dear all,
> >> > I haven't received any feedback so far on my proposal to make "justify" argument available in stats:::format.ftable
> >>
> >> > Is this list the appropriate place for this kind of proposal?
> >>
> >> Yes, it is.. Actually such a post is even a "role model" post
> >> for R-devel.
> >>
> >> > I hope this follow-up to my message won't be taken as rude. Of course it's not meant to be, but I'm not used to the R mailing lists...
> >>
> >> well, there could be said much, and many stories told here ... ;-)
> >>
> >> > Thank you in advance for your comments,
> >>
> >> > Best,
> >> > Thomas
> >>
> >> The main reasons for "no reaction" (for such nice post) probably
> >> are combination of the following
> >>
> >> - we are busy
> >> - if we have time, we think other things are more exciting
> >> - we have not used ftable much/at all and are not interested.
> >>
> >> Even though the first 2 apply to me, I'll have a 2nd look into
> >> your post now, and may end up well agreeing with your proposal.
> >>
> >> Martin Maechler
> >> ETH Zurich and R Core team
> >>
> >>
> >>
> >>
> >> >> Dear all,
> >> >>
> >> >> justify argument is hard coded in format.ftable:
> >> >>
> >> >> cbind(apply(LABS, 2L, format, justify = "left"),
> >> >> apply(DATA, 2L, format, justify = "right"))
> >> >>
> >> >> It would be useful to have the possibility to modify the argument between c("left", "right", "centre", "none") as in format.default.
> >> >>
> >> >> The lines could be changed to:
> >> >>
> >> >> if(length(justify) != 2)
> >> >> stop("justify must be length 2")
> >> >> cbind(apply(LABS, 2L, format, justify = justify[1]),
> >> >> apply(DATA, 2L, format, justify = justify[2]))
> >> >>
> >> >> The argument justify could defaults to c("left", "right") for backward compatibility.
> >> >>
> >> >> It could then allow:
> >> >> ftab <- ftable(wool + tension ~ breaks, warpbreaks)
> >> >> format.ftable(ftab, justify = c("none", "none"))
> >> >>
> >> >> Best regards,
> >> >>
> >> >> Thomas
>
>
> > --
> > Statistics & Software Consulting
> > GKX Group, GKX Associates Inc.
> > tel: 1-877-GKX-GROUP
> > email: ggrothendieck at gmail.com
--
Statistics & Software Consulting
GKX Group, GKX Associates Inc.
tel: 1-877-GKX-GROUP
email: ggrothendieck at gmail.com
More information about the R-devel
mailing list