R сгруппировать по одному столбцу и применить пользовательскую функцию к другому столбцу - PullRequest
0 голосов
/ 21 октября 2019

Скажем, у меня есть такой кадр данных:

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

Как применить эту функцию ко второму (числовому) столбцу для каждой группы A, B и C?:

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

Таким образом, результат выглядит следующим образом:

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

Я пробовал aggregate() и различные методы в dplyr, но либо a) код хочет применить функцию к обоим столбцам, что приводит кошибка или б) он применяет его к столбцу Data, но не сохраняет фрейм данных, поэтому я просто возвращаю вектор (или список векторов).

Ответы [ 2 ]

3 голосов
/ 21 октября 2019

С dplyr вы можете сделать:

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
0 голосов
/ 21 октября 2019

Использование data.table:

Код

setDT(dt)

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

Результат

> 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
...