saply для каждой группы, использующей dplyr - PullRequest
0 голосов
/ 03 марта 2019
df <- data.frame(group = rep(1:4, each = 10), 
                   x1 = rnorm(40),  x2 = rnorm(40), x3 = rnorm(40), x4 = rnorm(40), 
                   X5 = rnorm(40), x6 = rnorm(40), x7 = rnorm(40))

sapply(df[, 4:ncol(df)], function(x) sd(x)/mean(x))

Я хочу применить эту функцию для каждой группы.Как мне исправить приведенную ниже команду?

df %>% dplyr::group_by(group) %>% do.call(sapply(.[, 4:ncol(.)] function(x) sd(x)/mean(x)))

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

Рассмотрим базовые значения R by (объектно-ориентированная оболочка до tapply):

Данные (с учетом воспроизводимости)

set.seed(3219)
df <- data.frame(group = rep(1:4, each = 10), 
                   x1 = rnorm(40),  x2 = rnorm(40), x3 = rnorm(40), x4 = rnorm(40), 
                   X5 = rnorm(40), x6 = rnorm(40), x7 = rnorm(40))

by

by_list <- by(df, df$group, function(sub) 
    sapply(sub[, 4:ncol(sub)], function(x) sd(x)/mean(x))
)

# LIST
by_list 
# df$group: 1
#        x3        x4        X5        x6        x7 
# -1.077354  2.252270 -2.256086 -1.716327 -5.273771 
# ------------------------------------------------------------ 
# df$group: 2
#         x3         x4         X5         x6         x7 
#   2.580065   5.054094 -10.985927  32.716116   6.732901 
# ------------------------------------------------------------ 
# df$group: 3
#         x3         x4         X5         x6         x7 
#  -3.523565  -1.670539  -5.042595  -7.787303 -15.486737 
# ------------------------------------------------------------ 
# df$group: 4
#        x3        x4        X5        x6        x7 
# -5.597470 -9.842997  1.985010 33.657188  2.629724 

# MATRIX
do.call(rbind, by_list)

#          x3        x4         X5        x6         x7
# 1 -1.077354  2.252270  -2.256086 -1.716327  -5.273771
# 2  2.580065  5.054094 -10.985927 32.716116   6.732901
# 3 -3.523565 -1.670539  -5.042595 -7.787303 -15.486737
# 4 -5.597470 -9.842997   1.985010 33.657188   2.629724
0 голосов
/ 03 марта 2019

Если я понял ваш вопрос / цель, следующее даст результаты, которые вы ищете.Он использует пакет plyr поверх пакета dplyr.Скорее всего, вы столкнетесь с проблемами при использовании функции%>% с do.call, поскольку%>% - это просто ярлык для передачи предыдущего объекта в качестве первого аргумента последующей функции, а do.call ожидает именованную функциюв качестве первого аргумента

library(plyr)

df <- data.frame(group = rep(1:4, each = 10), 
                 x1 = rnorm(40),  x2 = rnorm(40), x3 = rnorm(40), x4 = rnorm(40), 
                 X5 = rnorm(40), x6 = rnorm(40), x7 = rnorm(40))

ddply(df,.(group),function(x) 
  { 
    sapply(x[,4:ncol(x)],function(y) sd(y)/mean(y))
  })

Дает следующие результаты

 group        x3        x4        X5         x6        x7
1     1  1.650401 -1.591829  1.509770   6.464991  3.520367
2     2 11.491301 -2.326737 -1.725810 -11.712510  2.293093
3     3 -3.623159 -1.416755  2.958689   1.629667 -4.318230
4     4  9.169641 -4.219095  2.083300   1.985500 -1.678107
...