Skip to contents

Group creates a grouped variant of an object of class "data.frame" or of class "data.set", for which methods for with and within are defined, so that these well-known functions can be applied "groupwise".

Usage

# Create an object of class "grouped.data" from a
# data frame or a data set.
Groups(data,by,...)
# S3 method for data.frame
Groups(data,by,...)
# S3 method for data.set
Groups(data,by,...)
# S3 method for grouped.data
Groups(data,by,...)

# Recombine grouped data into a data fame or a data set
recombine(x,...)
# S3 method for grouped.data.frame
recombine(x,...)
# S3 method for grouped.data.set
recombine(x,...)

# Recombine grouped data and coerce the result appropriately:
# S3 method for grouped.data
as.data.frame(x,...)
# S4 method for grouped.data.frame
as.data.set(x,row.names=NULL,...)
# S4 method for grouped.data.set
as.data.set(x,row.names=NULL,...)

# Methods of the generics "with" and "within" for grouped data
# S3 method for grouped.data
with(data,expr,...)
# S3 method for grouped.data
within(data,expr,recombine=FALSE,...)

# This is equivalent to with(Groups(data,by),expr,...)
withGroups(data,by,expr,...)
# This is equivalent to within(Groups(data,by),expr,recombine,...)
withinGroups(data,by,expr,recombine=TRUE,...)

Arguments

data

an object of the classes "data.frame", "data.set" if an argument to Groups, withGroups, withinGroups,

by

a formula with the factors the levels of which define the groups.

expr

an expression, or several expressions enclosed in curly braces.

recombine

a logical vector; should the resulting grouped data be recombined?

x

an object of class "grouped.data".

row.names

an optional character vector with row names.

...

other arguments, ignored.

Details

When applied to a data frame Groups returns an object with class attributes "grouped.data.frame", "grouped.data", and "data.frame", when applied do an object with class "data.set", it returns an object with class attributes "grouped.data.set", "grouped.data", and "data.set".

When applied to objects with class attributed "grouped.data", both the functions with() amd within() evaluate expr separately for each group defined by Groups. with() returns an array composed of the results of expr, while within() returns a modified copy of its data argument, which will be a "grouped.data" object ("grouped.data.frame" or "grouped.data.set"), unless the argument recombine=TRUE is set.

The expression expr may contain references to the variables n_, N_, and i_. n_ is equal to the size of the respective group (the number of rows belonging to it), while N_ is equal to the total number of observations in all groups. The variable i_ equals to the indices of the rows belonging to the respective group of observations.

Examples

some.data <- data.frame(x=rnorm(n=100))
some.data <- within(some.data,{
    f <- factor(rep(1:4,each=25),labels=letters[1:4])
    g <- factor(rep(1:5,each=4,5),labels=LETTERS[1:5])
    y <- x + rep(1:4,each=25) +  0.75*rep(1:5,each=4,5)
})

# For demonstration purposes, we create an
# 'empty' group:
some.data <- subset(some.data,
                       f!="a" | g!="C")

some.grouped.data <- Groups(some.data,
                           ~f+g)    

# Computing the means of y for each combination f and g
group.means <- with(some.grouped.data,
                    mean(y))
group.means
#>    g
#> f          A        B        C        D        E
#>   a 1.403459 1.609090       NA 5.007543 4.130731
#>   b 2.563520 4.504278 4.197527 5.089312 5.601830
#>   c 3.911676 4.437842 4.727768 6.512211 7.283651
#>   d 4.694704 5.532708 6.500390 6.001904 7.297987

# Obtaining a groupwise centered variant of y
some.grouped.data <- within(some.grouped.data,{
    y.cent <- y - mean(y)
},recombine=FALSE)

# The groupwise centered variable should have zero mean
# whithin each group
group.means <- with(some.grouped.data,
                    round(mean(y.cent),15))
group.means
#>    g
#> f   A B  C D E
#>   a 0 0 NA 0 0
#>   b 0 0  0 0 0
#>   c 0 0  0 0 0
#>   d 0 0  0 0 0

# The following demonstrates the use of n_, N_, and i_
# An external copy of y
y1 <- some.data$y
group.means.n <- with(some.grouped.data,
                      c(mean(y),  # Group means for y
                        n_,       # Group sizes
                        sum(y)/n_,# Group means for y
                        n_/N_,    # Relative group sizes
                        sum(y1)/N_,# NOT the grand mean
                        sum(y1[i_])/n_)) # Group mean for y1
group.means.n
#> , , g = A
#> 
#>                 f
#>                           a          b          c          d
#>   mean(y)        1.40345883 2.56351976 3.91167557 4.69470447
#>   n_             8.00000000 4.00000000 4.00000000 4.00000000
#>   sum(y)/n_      1.40345883 2.56351976 3.91167557 4.69470447
#>   n_/N_          0.08333333 0.04166667 0.04166667 0.04166667
#>   sum(y1)/N_     4.76405581 4.76405581 4.76405581 4.76405581
#>   sum(y1[i_])/n_ 1.40345883 2.56351976 3.91167557 4.69470447
#> 
#> , , g = B
#> 
#>                 f
#>                           a          b          c          d
#>   mean(y)        1.60908966 4.50427814 4.43784170 5.53270834
#>   n_             5.00000000 7.00000000 4.00000000 4.00000000
#>   sum(y)/n_      1.60908966 4.50427814 4.43784170 5.53270834
#>   n_/N_          0.05208333 0.07291667 0.04166667 0.04166667
#>   sum(y1)/N_     4.76405581 4.76405581 4.76405581 4.76405581
#>   sum(y1[i_])/n_ 1.60908966 4.50427814 4.43784170 5.53270834
#> 
#> , , g = C
#> 
#>                 f
#>                   a        b        c          d
#>   mean(y)        NA 4.197527 4.727768 6.50038973
#>   n_             NA 6.000000 6.000000 4.00000000
#>   sum(y)/n_      NA 4.197527 4.727768 6.50038973
#>   n_/N_          NA 0.062500 0.062500 0.04166667
#>   sum(y1)/N_     NA 4.764056 4.764056 4.76405581
#>   sum(y1[i_])/n_ NA 4.197527 4.727768 6.50038973
#> 
#> , , g = D
#> 
#>                 f
#>                           a          b          c          d
#>   mean(y)        5.00754263 5.08931237 6.51221079 6.00190384
#>   n_             4.00000000 4.00000000 7.00000000 5.00000000
#>   sum(y)/n_      5.00754263 5.08931237 6.51221079 6.00190384
#>   n_/N_          0.04166667 0.04166667 0.07291667 0.05208333
#>   sum(y1)/N_     4.76405581 4.76405581 4.76405581 4.76405581
#>   sum(y1[i_])/n_ 5.00754263 5.08931237 6.51221079 6.00190384
#> 
#> , , g = E
#> 
#>                 f
#>                           a          b          c          d
#>   mean(y)        4.13073149 5.60182984 7.28365123 7.29798732
#>   n_             4.00000000 4.00000000 4.00000000 8.00000000
#>   sum(y)/n_      4.13073149 5.60182984 7.28365123 7.29798732
#>   n_/N_          0.04166667 0.04166667 0.04166667 0.08333333
#>   sum(y1)/N_     4.76405581 4.76405581 4.76405581 4.76405581
#>   sum(y1[i_])/n_ 4.13073149 5.60182984 7.28365123 7.29798732
#> 

# Names can be attached to the groupwise results
with(some.grouped.data,
     c(Centered=round(mean(y.cent),15),
       Uncentered=mean(y)))
#> , , g = A
#> 
#>             f
#>                     a       b        c        d
#>   Centered   0.000000 0.00000 0.000000 0.000000
#>   Uncentered 1.403459 2.56352 3.911676 4.694704
#> 
#> , , g = B
#> 
#>             f
#>                    a        b        c        d
#>   Centered   0.00000 0.000000 0.000000 0.000000
#>   Uncentered 1.60909 4.504278 4.437842 5.532708
#> 
#> , , g = C
#> 
#>             f
#>               a        b        c       d
#>   Centered   NA 0.000000 0.000000 0.00000
#>   Uncentered NA 4.197527 4.727768 6.50039
#> 
#> , , g = D
#> 
#>             f
#>                     a        b        c        d
#>   Centered   0.000000 0.000000 0.000000 0.000000
#>   Uncentered 5.007543 5.089312 6.512211 6.001904
#> 
#> , , g = E
#> 
#>             f
#>                     a       b        c        d
#>   Centered   0.000000 0.00000 0.000000 0.000000
#>   Uncentered 4.130731 5.60183 7.283651 7.297987
#> 

some.data.ungrouped <- recombine(some.grouped.data)
str(some.data.ungrouped)
#> 'data.frame':	96 obs. of  5 variables:
#>  $ x     : num  -1.768 0.517 1.221 -2.64 -0.379 ...
#>  $ y     : num  -0.0176 2.2673 2.9706 -0.8896 2.1212 ...
#>  $ g     : Factor w/ 5 levels "A","B","C","D",..: 1 1 1 1 2 2 2 2 4 4 ...
#>  $ f     : Factor w/ 4 levels "a","b","c","d": 1 1 1 1 1 1 1 1 1 1 ...
#>  $ y.cent: num  -1.421 0.864 1.567 -2.293 0.512 ...

# It all works with "data.set" objects
some.dataset <- as.data.set(some.data)
some.grouped.dataset <- Groups(some.dataset,~f+g)

with(some.grouped.dataset,
     c(Mean=mean(y),
       Variance=var(y)))
#> , , g = A
#> 
#>           f
#>                   a         b         c         d
#>   Mean     1.403459 2.5635198 3.9116756 4.6947045
#>   Variance 1.927992 0.3963322 0.3397217 0.8643241
#> 
#> , , g = B
#> 
#>           f
#>                    a         b         c         d
#>   Mean     1.6090897 4.5042781 4.4378417 5.5327083
#>   Variance 0.3482943 0.7598832 0.2059886 0.1219164
#> 
#> , , g = C
#> 
#>           f
#>             a         b         c         d
#>   Mean     NA 4.1975268 4.7277683 6.5003897
#>   Variance NA 0.3648514 0.1695483 0.9125847
#> 
#> , , g = D
#> 
#>           f
#>                    a         b         c        d
#>   Mean     5.0075426 5.0893124 6.5122108 6.001904
#>   Variance 0.3721454 0.1957726 0.5876143 1.776912
#> 
#> , , g = E
#> 
#>           f
#>                   a        b         c        d
#>   Mean     4.130731 5.601830 7.2836512 7.297987
#>   Variance 3.026132 1.084887 0.7245219 0.623688
#> 

# The following two expressions are equivalent:
with(Groups(some.data,~f+g),mean(y))
#>    g
#> f          A        B        C        D        E
#>   a 1.403459 1.609090       NA 5.007543 4.130731
#>   b 2.563520 4.504278 4.197527 5.089312 5.601830
#>   c 3.911676 4.437842 4.727768 6.512211 7.283651
#>   d 4.694704 5.532708 6.500390 6.001904 7.297987
withGroups(some.data,~f+g,mean(y))
#>    g
#> f          A        B        C        D        E
#>   a 1.403459 1.609090       NA 5.007543 4.130731
#>   b 2.563520 4.504278 4.197527 5.089312 5.601830
#>   c 3.911676 4.437842 4.727768 6.512211 7.283651
#>   d 4.694704 5.532708 6.500390 6.001904 7.297987

# The following two expressions are equivalent:
some.data <- within(Groups(some.data,~f+g),{
    y.cent <- y - mean(y)
    y.cent.1 <- y - sum(y)/n_
})

some.data <- withinGroups(some.data,~f+g,{
    y.cent <- y - mean(y)
    y.cent.1 <- y - sum(y)/n_
})

# Both variants of groupwise centred varaibles should
# have zero groupwise means:
withGroups(some.data,~f+g,{
    c(round(mean(y.cent),15),
      round(mean(y.cent.1),15))
})
#> , , g = A
#> 
#>    f
#>     a b c d
#>   1 0 0 0 0
#>   2 0 0 0 0
#> 
#> , , g = B
#> 
#>    f
#>     a b c d
#>   1 0 0 0 0
#>   2 0 0 0 0
#> 
#> , , g = C
#> 
#>    f
#>      a b c d
#>   1 NA 0 0 0
#>   2 NA 0 0 0
#> 
#> , , g = D
#> 
#>    f
#>     a b     c     d
#>   1 0 0 0e+00 0e+00
#>   2 0 0 1e-15 1e-15
#> 
#> , , g = E
#> 
#>    f
#>     a b c d
#>   1 0 0 0 0
#>   2 0 0 0 0
#>