Как разделить-применить-объединить несколько переменных/столбцов в R

Я хотел бы выполнить функцию для нескольких переменных по группам.

Поддельные данные;

df<-data.frame(rnorm(100,mean=10), 
               rnorm(100,mean=15),
               rnorm(100,mean=20),
               rep(letters[1:10],each=10)
               )
colnames(df)<-c("var1","var2","var3","group1")

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

Обычно для этого я использую пакет PLYR;

library(plyr)    
ddply(df, "group1", transform, centered_var1= scale(var1, scale=FALSE))

Однако мне не удалось успешно зациклить эту функцию или придумать другой способ с минимальным кодом для этого.

Я открыт для решений, отличных от PLYR... Моим главным критерием является сведение кода к минимуму.


person Dave M    schedule 15.07.2015    source источник


Ответы (3)


Возможно, вам нужна функция colwise.

library("plyr")
ddply(df, .(group1), colwise(scale, scale = FALSE))
person Josh W.    schedule 15.07.2015
comment
Я расщепляюсь, но этот ответ кажется наиболее близким к моему первоначальному вопросу, возвращает объект фрейма данных, хотя все еще нужно cbind() объединить старые и новые переменные. Также необходимо подмножить мой полный фрейм данных, прежде чем использовать этот подход. Кто-нибудь знает, как вы могли бы передать ddply только переменные, для которых вы хотите выполнить функцию (предпочтительно как вектор символов), чтобы избежать подмножества? - person Dave M; 16.07.2015
comment
Отвечая на вопрос в моем комментарии выше; Можно использовать аргумент .cols= из colwise для передачи конкретных переменных функции из полного фрейма данных. например, .cols=c("var1","var2") - person Dave M; 16.07.2015

Использование dplyr

library(dplyr)
df %>% group_by(group1) %>%
  mutate_each(funs(scale(., scale=F))) -> res
person Rorschach    schedule 15.07.2015
comment
Это приводит к сбою R 3.1.3 в Windows 7. Я не очень хорошо знаком с dplyr, поэтому не смог найти, что не так. Есть идеи? ................................................. Ошибка в withCallingHandlers(tryCatch(evalq(scale(c(9.151793483555958, : объект .rcpp_warning_recorder) не найден) Это приложение запросило среду выполнения, чтобы завершить его необычным образом. Пожалуйста, свяжитесь со службой поддержки приложения для получения дополнительной информации. - person Dave M; 15.07.2015
comment
@DaveM о, возможно, переустановите Rcpp и обновитесь до R 3.2, см. com/questions/28966800/ - person Rorschach; 15.07.2015
comment
Спасибо. Это решило проблему. - person Dave M; 15.07.2015

Это то, что вы хотите?

ddply(df, "group1", transform, centered_var1= scale(var1, scale=FALSE),
      centered_var2 = scale(var2, scale=FALSE),
      centered_var3 = scale(var3, scale=FALSE))
person Heisenberg    schedule 15.07.2015
comment
Спасибо. Я не понимал, что могу продолжать добавлять аргументы для дополнительных переменных, подобных этой. Есть ли способ автоматизировать это, при котором мне не нужно вводить каждую переменную вручную (например, индексирование в цикле for?) - person Dave M; 15.07.2015