Luther_Blissett
Luther_Blissett

Reputation: 327

R group by one column and apply custom function to another column

Say I have a data frame like this:

x <- data.frame(x = c(rep("A", 5), rep("B", 5), rep("C", 5)), Data = rep(1:5, 3))

How do I apply this function to the second (numerical) column by each group A, B and C?:

Percent <- function(x){(x/length(x))*100}

So the result is like this:

x Data
 A 20
 A 40
 A 60
 A 80
 A 100
 B 20
 B 40
 ...etc

I have tried aggregate() and various methods in dplyr but either a) the code wants to apply the function to both columns, resulting in an error or b) it applies it to the Data column but doesn't preserve the data frame so I just get back a vector (or list of vectors).

Upvotes: 0

Views: 977

Answers (2)

JDG
JDG

Reputation: 1364

Using data.table:

Code

setDT(dt)

dt = data.table(x); percent = function(x){100*x/length(x)}
dt[, Percent := percent(Data), keyby=x]

Result

> dt
    x Data Percent
 1: A    1      20
 2: A    2      40
 3: A    3      60
 4: A    4      80
 5: A    5     100
 6: B    1      20
 7: B    2      40
 8: B    3      60
 9: B    4      80
10: B    5     100
11: C    1      20
12: C    2      40
13: C    3      60
14: C    4      80
15: C    5     100

Upvotes: 0

tmfmnk
tmfmnk

Reputation: 39858

With dplyr, you can do:

fun <- function(x) {
 (x/n()) * 100
}

x %>%
 group_by(x) %>%
 mutate(Data = fun(Data))

   x      Data
   <fct> <dbl>
 1 A        20
 2 A        40
 3 A        60
 4 A        80
 5 A       100
 6 B        20
 7 B        40
 8 B        60
 9 B        80
10 B       100

Upvotes: 3

Related Questions