Reputation: 327
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
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
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