2016-05-13 2 views
3

У меня есть кадр данных, который содержит некоторую статистику для ряда переменных и сценариев. Данные выглядит следующим образом:tidyr extract regular expression

df <- data.frame(
    Scenario = c('base','stress','extreme'), 
    x_min = c(-3,-2, -2.5), 
    x_mean = c(0,0.25, 1), 
    x_max = c(2, 1, 3), 
    y_min = c(-1.5, -2, -3), 
    y_mean = c(1, 2, 3), 
    y_max = c(5, 3, 3.5), 
    z_min = c(0, 1, 3), 
    z_mean = c(0.25, 2, 5), 
    z_max = c(2, 4, 7) 
) 

    Scenario x_min x_mean x_max y_min y_mean y_max z_min z_mean z_max 
1  base -3.0 0.00  2 -1.5  1 5.0  0 0.25  2 
2 stress -2.0 0.25  1 -2.0  2 3.0  1 2.00  4 
3 extreme -2.5 1.00  3 -3.0  3 3.5  3 5.00  7 

Я хотел бы использовать tidyr соберемся и извлекать функции (в аналогичной манере ответа Хедли к this question), чтобы получить данные в формате, как:

new_df 
    Scenario variable min mean max 
1  base  x -3.0 0.00 2.0 
2 stress  x -2.0 0.25 1.0 
3 extreme  x -2.5 1.00 3.0 
4  base  y -1.5 1.00 5.0 
5 stress  y -2.0 2.00 3.0 
6 extreme  y -3.0 3.00 3.5 
7  base  z 0.0 0.25 2.0 
8 stress  z 1.0 2.00 4.0 
9 extreme  z 3.0 5.00 7.0 

команда Я до сих пор выгляжу так:

new_df <- df %>% 
      gather(key, value, -Scenario) %>% 
      extract(key, c("min", "mean", "max"), "regex") 

Это регулярное выражение, с которым я борюсь. После ответа на вопрос, указанным выше, я попробовал:

"_min|_mean|_max" --> idea being to capture the 3 different groups 

Я получаю ошибку выглядит так:

Error in names(l) <- into : 
    'names' attribute [3] must be the same length as the vector [0] 

То, что я думаю, что эта ошибка говорит это регулярное выражение не " нахождение «3 группы для сортировки в c("min","mean","max") Я прошел ее.

Какое регулярное выражение будет работать? Или есть другой лучший метод?

ответ

3

Все, что вам нужно, это

df %>% gather(var, val, -Scenario) %>% 
    separate(var, into = c('var', 'stat'), sep = '_') %>% 
    spread(stat, val) 
# Scenario var max mean min 
# 1  base x 2.0 0.00 -3.0 
# 2  base y 5.0 1.00 -1.5 
# 3  base z 2.0 0.25 0.0 
# 4 extreme x 3.0 1.00 -2.5 
# 5 extreme y 3.5 3.00 -3.0 
# 6 extreme z 7.0 5.00 3.0 
# 7 stress x 1.0 0.25 -2.0 
# 8 stress y 3.0 2.00 -2.0 
# 9 stress z 4.0 2.00 1.0 

Поскольку первоначальные имена столбцов красиво отформатированы с подчеркиванием, отделяющим переменной и статистику, separate все, что нужно, чтобы разделить их на две колонки. spread будет перестраиваться от длинного до широкого.

+1

Именно то, что мне нужно! В качестве примечания я должен был сделать аргумент 'sep'' отдельного' регулярного выражения, потому что мои заголовки столбцов фактически содержали несколько подчеркиваний (например, 'stat_1_min, stat_2_min'). Регулярное выражение, которое я использовал, было '(_) (?!. * _)' – reidjax

2

Это можно легко сделать с melt из data.table как это может занять несколько patterns в measure

library(data.table) 
nm1 <- unique(substr(names(df)[-1], 1, 1)) 
melt(setDT(df), measure = patterns("min$", "mean$", "max$"), 
     value.name= c("min", "mean", "max"))[, variable := nm1[variable]][] 
# Scenario variable min mean max 
#1:  base  x -3.0 0.00 2.0 
#2: stress  x -2.0 0.25 1.0 
#3: extreme  x -2.5 1.00 3.0 
#4:  base  y -1.5 1.00 5.0 
#5: stress  y -2.0 2.00 3.0 
#6: extreme  y -3.0 3.00 3.5 
#7:  base  z 0.0 0.25 2.0 
#8: stress  z 1.0 2.00 4.0 
#9: extreme  z 3.0 5.00 7.0