简体   繁体   中英

Grouping the dataframe based on one variable

I have a dataframe with 10 variables all of them numeric, and one of the variable name is age, I want to group the observation based on age.example. age 17 to 18 one group, 19-22 another group and then each row should be attached to each group. And resulting should be a dataframe for further manipulations. Model of the dataframe:

A   B   AGE
25  50  17
30  42  22
50  60  19
65  105 17
355 400 21
68  47  20
115 98  18
25  75  19

And I want result like

17-18 
A   B   AGE
25  50  17
65  105 17
115 98  18

19-22
A   B   AGE
30  42  22
50  60  19
355 400 21
68  47  20
115 98  18
25  75  19

I did group the dataset according to Age var using the split function, now my concern is how I could manipulate the grouped data. Eg:the answer looked like

$1

  A   B   AGE
  25  50  17
  65  105 17
  115 98  18

$2
A   B   AGE
    30  42  22
    50  60  19
    355 400 21
    68  47  20
    115 98  18
    25  75  19

My question is how can I access each group for further manipulation? for eg: if I want to do t-test for each group separately?

The split function will work with dataframes. Use either cut with 'breaks' or findInterval with an appropriate set of cutpoints (named 'vec' if you are using named parameters) as the criterion for grouping, the second argument to split . The default for cut is intervals closed on the right and default for findInterval is closed on the left.

> split(dat, findInterval(dat$AGE, c(17, 19.5, 22.5)))
$`1`
    A   B AGE
1  25  50  17
3  50  60  19
4  65 105  17
7 115  98  18
8  25  75  19

$`2`
    A   B AGE
2  30  42  22
5 355 400  21
6  68  47  20

Here is the approach with cut

lst <- split(df1, cut(df1$AGE, breaks=c(16, 18, 22), labels=FALSE))
lst
# $`1`
#   A   B AGE
#1  25  50  17
#4  65 105  17
#7 115  98  18

#$`2`
#   A   B AGE
#2  30  42  22
#3  50  60  19
#5 355 400  21
#6  68  47  20
#8  25  75  19

Update

If you need to find the sum , mean of columns for each "list" element

lapply(lst, function(x) rbind(colSums(x[-3]),colMeans(x[-3])))

But, if the objective is to find the summary statistics based on the group, it can be done using any of the aggregating functions

 library(dplyr)
 df1 %>% 
     group_by(grp=cut(AGE, breaks=c(16, 18, 22), labels=FALSE)) %>% 
     summarise_each(funs(sum=sum(., na.rm=TRUE),
                      mean=mean(., na.rm=TRUE)), A:B)
 #   grp A_sum B_sum    A_mean    B_mean
 #1   1   205   253  68.33333  84.33333
 #2   2   528   624 105.60000 124.80000

Or using aggregate from base R

 do.call(data.frame,
   aggregate(cbind(A,B)~cbind(grp=cut(AGE, breaks=c(16, 18, 22), 
    labels=FALSE)), df1, function(x) c(sum=sum(x), mean=mean(x))))

data

df1 <- structure(list(A = c(25L, 30L, 50L, 65L, 355L, 68L, 115L, 25L
), B = c(50L, 42L, 60L, 105L, 400L, 47L, 98L, 75L), AGE = c(17L, 
22L, 19L, 17L, 21L, 20L, 18L, 19L)), .Names = c("A", "B", "AGE"
), class = "data.frame", row.names = c(NA, -8L))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM