2015-06-30 3 views
4

Воспользуйтесь приведенным ниже примером.Заменить столбцы «каноническим» способом после mutate_each или summaryise_each

library(dplyr) 
temp <- data.frame(lapply(1:3, function(i) rnorm(5, 0, 1))) 
names(temp) <- paste0("X", 1:3) 

temp_each <- 
    temp %>% 
    mutate_each(funs(mean, median)) 

Рассматривая имена temp_each, мы видим, что

> names(temp_each) 
[1] "X1"  "X2"  "X3"  "X1_mean" "X2_mean" "X3_mean" "X1_median" "X2_median" "X3_median" 

, то есть конечные столбцы в группах по три, всегда упорядоченный X1, X2, X3 + функция применяется.

Однако, я хотел бы, чтобы это выглядело, как это

[1] "X1"  "X1_mean" "X1_median" "X2"  "X2_mean" "X2_median" "X3"  "X3_mean" "X3_median" 

Кто-нибудь знает, как осуществить это, предпочтительно с использованием dplyr, для кадра данных со многими многими колонками и произвольными именами столбцов?

+2

Вы можете просто изменить порядок столбцов, отсортировав имена в алфавитном порядке? 'temp_each [, order (namesp (temp_each))]' делает ли это то, что вам нужно? – chappers

+0

Это хорошее временное решение, но это может быть необязательно сохранить порядок первоначальных имен, если они не являются 'X1',' X2' и т. Д. ... Я немного изменил вопрос, спасибо – Alex

+1

Вы можете проверить ' mixedorder' from gtools –

ответ

5

Здесь вы можете использовать mixedorder из gtools

library(gtools) 
temp_each[,mixedorder(colnames(temp_each))] 

#   X1 X1_mean X1_median   X2 X2_mean X2_median 
#1 0.28285115 -0.4369067 0.08556155 -0.9402162 -0.9857593 -0.7676634 
#2 -1.29193398 -0.4369067 0.08556155 -0.5442052 -0.9857593 -0.7676634 
#3 -1.42261044 -0.4369067 0.08556155 -0.7676634 -0.9857593 -0.7676634 
#4 0.16159810 -0.4369067 0.08556155 -2.2270920 -0.9857593 -0.7676634 
#5 0.08556155 -0.4369067 0.08556155 -0.4496198 -0.9857593 -0.7676634 
#   X3 X3_mean X3_median 
#1 0.04606554 0.0923336 -0.08168136 
#2 -0.08168136 0.0923336 -0.08168136 
#3 0.90535333 0.0923336 -0.08168136 
#4 -0.15699052 0.0923336 -0.08168136 
#5 -0.25107897 0.0923336 -0.08168136 
2

С базой R вы могли бы попробовать это:

> temp_each[order(colnames(temp_each))] 
#   X1 X1_mean X1_median   X2 X2_mean X2_median   X3 X3_mean X3_median 
# 1 0.4142743 -0.4389318 -0.285517 1.8662158 0.3534017 -0.2308971 1.3593561 0.478106 0.6306579 
# 2 -0.8031115 -0.4389318 -0.285517 -0.2308971 0.3534017 -0.2308971 -0.6160166 0.478106 0.6306579 
# 3 -1.8729143 -0.4389318 -0.285517 1.0171626 0.3534017 -0.2308971 0.2634524 0.478106 0.6306579 
# 4 0.3526097 -0.4389318 -0.285517 -0.6378480 0.3534017 -0.2308971 0.6306579 0.478106 0.6306579 
# 5 -0.2855170 -0.4389318 -0.285517 -0.2476247 0.3534017 -0.2308971 0.7530800 0.478106 0.6306579 
+1

Это не даст желаемого результата, если есть такие столбцы, как X10, X20 и т. Д. –

+1

Согласен. В этом случае можно добавить начальные нули перед номером индекса для меньших чисел с помощью манипуляции с регулярным выражением. Хотя это возможно, ваше решение кажется более простым, если оно может обрабатывать эти случаи автоматически. – RHertel

1

Спасибо всем за ответы, используя базу R или иным образом.

Это мое избранное R решение.

old_names <- names(temp) 
new_names <- unlist(lapply(old_names, function(old_name) paste0(old_name, c("_mean", "_median")))) 
temp_each <- temp_each[new_names] 

Однако, я теперь работал, как сделать это в dplyr, используя стандартную оценку, из этого ответа: Group by multiple columns in dplyr, using string vector input

Это довольно запутанным.

temp <- data.frame(lapply(1:3, function(i) rnorm(5, 0, 1))) 
names(temp) <- paste0("X", 1:3) 

old_names <- names(temp) 
new_names <- unlist(lapply(old_names, function(old_name) paste0(old_name, c("_mean", "_median")))) 


temp_each <- 
    temp %>% 
    mutate_each(funs(mean, median)) %>% 
    select_(.dots = lapply(new_names, as.symbol))