Laura
Laura

Reputation: 113

Divide data frame number equally in groups

I have a data frame with a column of names and more columns containing properties coded by 0 and 1 (equal to no and yes).

     Name     Running   Cycling
1     Adam     1         0
2     Steve    0         1
3     Aaron    1         1
4     Nick     1         0
5     Paul     1         0
6     Stuart   1         0

I now want to divide the yes equally into a given number of groups column-wise for all 1s and add the number of the related group in an additional column. If we would divide Running and Cycling in two groups each this should be the result:

Name     Running   Cycling  Running-Group Cycling-Group
1     Adam     1         0        1           0 
2     Steve    0         1        0           1
3     Aaron    1         1        1           2
4     Nick     1         0        1           0
5     Paul     1         0        2           0
6     Stuart   1         0        2           0

I can get the group number with:

ceiling(sum(column)/100*groups)

I am sure there is an easy way with R, however I couldn't find a solution which ignores the 0s (nos) and adds the group number only to the 1s (yes).

Thanks for your help.

Upvotes: 0

Views: 145

Answers (2)

akrun
akrun

Reputation: 886978

May be this helps

nm1 <- paste(names(df1)[-1], 'Group', sep="_")
df1[nm1] <- lapply(df1[-1], function(x) {
                  x1 <- x==1
                  x[x1] <- gl(sum(x1),ceiling(sum(x1)/2), sum(x1))
                   x})
 df1
 #    Name Running Cycling Running_Group Cycling_Group
 #1   Adam       1       0             1             0
 #2  Steve       0       1             0             1
 #3  Aaron       1       1             1             2
 #4   Nick       1       0             1             0
 #5   Paul       1       0             2             0
 #6 Stuart       1       0             2             0

Upvotes: 1

G. Grothendieck
G. Grothendieck

Reputation: 269471

Use the grps function shown below:

grp <- function(x) { 
  s <- seq_along(x)
  x * ((s > mean(s)) + 1)
}

grps <- function(x) ave(x, x, FUN = grp)

transform(DF, 
  Running_Group = grps(Running),
  Cycling_Group = grps(Cycling))

giving:

    Name Running Cycling Running_Group Cycling_Group
1   Adam       1       0             1             0
2  Steve       0       1             0             1
3  Aaron       1       1             1             2
4   Nick       1       0             1             0
5   Paul       1       0             2             0
6 Stuart       1       0             2             0

Note: We used the following as DF:

Lines <- "     Name     Running   Cycling
1     Adam     1         0
2     Steve    0         1
3     Aaron    1         1
4     Nick     1         0
5     Paul     1         0
6     Stuart   1         0"

DF <- read.table(text = Lines, header = TRUE)

Upvotes: 0

Related Questions