Манипуляции с уровнями, производимые функцией cut R

Я хочу проделать некоторые манипуляции с уровнями, создаваемыми функцией cut R. Я хочу иметь exp(Labs) в моем MWE.

set.seed(12345)
Y <- rnorm(n = 50, mean = 500, sd = 1)
Y1 <-  cut(log(Y), 5)
Labs <- levels(Y1)
Labs
[1] "(6.21,6.212]"  "(6.212,6.213]" "(6.213,6.215]" "(6.215,6.217]" "(6.217,6.219]"

exp(cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", Labs) ),
      upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", Labs) )))
        lower    upper

[1,] 497.7013 498.6976
[2,] 498.6976 499.1966
[3,] 499.1966 500.1960
[4,] 500.1960 501.1974
[5,] 501.1974 502.2008

Вопрос

Как я могу попасть сюда exp(Labs)?

Желаемый результат

"(497.7013, 498.6976]"  "(498.6976, 499.1966]" "(499.1966, 500.1960]" "(500.1960, 501.1974]"  "(501.1974, 502.2008]" 

Отредактировано

На основе ответа @akrun:

    Labs1 <- c("(-2.32,0.99]", "(0.99,4.28]", "(4.28,7.58]", "(7.58,10.9]", "(10.9,14.2]")

Labs1
    [1] "(-2.32,0.99]" "(0.99,4.28]"  "(4.28,7.58]"  "(7.58,10.9]"  "(10.9,14.2]"

    exp(cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", Labs1) ),
              upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", Labs1) )))

            lower        upper
[1,] 9.827359e-02 2.691234e+00
[2,] 2.691234e+00 7.224044e+01
[3,] 7.224044e+01 1.958629e+03
[4,] 1.958629e+03 5.417636e+04
[5,] 5.417636e+04 1.468864e+06


    gsubfn('([0-9.]+)', ~round(exp(as.numeric(x)),4), Labs1)

[1] "(-10.1757,2.6912]"         "(2.6912,72.2404]"          "(72.2404,1958.629]"       
[4] "(1958.629,54176.3638]"     "(54176.3638,1468864.1897]"

    res1 <-  exp(as.data.frame(t(sapply(strsplit(Labs1, '[^0-9.]+'), 
                                       function(x) as.numeric(x[-1])))))
    sprintf('(%s]', do.call(paste, c(round(res1,4), sep=", ")))


[1] "(10.1757, 2.6912]"          "(2.6912, 72.2404]"          "(72.2404, 1958.629]"       
[4] "(1958.629, 54176.3638]"     "(54176.3638, 1468864.1897]"

r cut
person MYaseen208    schedule 29.07.2015    source источник
comment
cut был исполнен log(Y). Я думаю, ему нужны метки в терминах Y, что означало бы возведение в степень каждое из значений в метках.   -  person Benjamin    schedule 29.07.2015
comment
Вы пробовали с paste Что-то вроде apply(res, 1, FUN= function(x) paste0('(', paste(round(x,4), collapse=", "), ']')), если res - это результат, полученный с exp(cbind(..   -  person akrun    schedule 29.07.2015
comment
Или, если на выходе получается кадр data.frame, полученный с помощью res <- exp(data.frame(.., sprintf('(%s]', do.call(paste, c(round(res,4), sep=", ")))   -  person akrun    schedule 29.07.2015
comment
Или с матрицей: paste0("(", round(res[, 1], 3), ",", round(res[, 2], 3), "]")   -  person Benjamin    schedule 29.07.2015
comment
Спасибо @akrun за полезный комментарий. Пожалуйста, измените свой комментарий, чтобы ответить. Еще раз спасибо.   -  person MYaseen208    schedule 29.07.2015
comment
Я обновил пост. Разве это не правильный вывод?   -  person akrun    schedule 29.07.2015


Ответы (1)


Компактным вариантом было бы использование gsubfn. Мы сопоставляем числовые элементы с точками (([0-9.]+)) в аргументе pattern и заменяем совпавший, сначала преобразовывая его в «числовой», берем exp и round.

library(gsubfn)
gsubfn('([-0-9.]+)', ~round(exp(as.numeric(x)),4), Labs)
#[1] "(497.7013,498.6976]" "(498.6976,499.1966]" "(499.1966,500.196]" 
#[4] "(500.196,501.1974]"  "(501.1974,502.2008]"

ПРИМЕЧАНИЕ. Это зависит от используемого нами шаблона.


Другой способ избежать двух вызовов sub - strsplit. Мы split на нечисловых элементах. Результатом будет list, поэтому мы можем использовать либо lapply/sapply, чтобы перебирать элементы списка, преобразовывать в класс numeric и создавать data.frame с двумя столбцами.

res <-  exp(as.data.frame(t(sapply(strsplit(Labs, '[^-0-9.]+'), 
              function(x) as.numeric(x[-1])))))

Относительно получения ожидаемого результата на основе кода OP. Я изменил cbind на data.frame в исходном коде, чтобы можно было использовать do.call.

 res <-  exp(data.frame(lower = as.numeric( sub("\\((.+),.*", "\\1", Labs) ),
         upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", Labs) )))

Мы paste элементы строки 'res' (do.call(paste0), а затем добавляем дополнительные круглые скобки с sprintf или другим paste

  sprintf('(%s]', do.call(paste, c(round(res,4), sep=", ")))
  #[1] "(497.7013, 498.6976]" "(498.6976, 499.1966]" "(499.1966, 500.196]" 
  #[4] "(500.196, 501.1974]"  "(501.1974, 502.2008]"

Обновлять

Проверка вывода с помощью 'Labs1'

 gsubfn('([-0-9.]+)', ~round(exp(as.numeric(x)),4), Labs1)
 #[1] "(0.0983,2.6912]"           "(2.6912,72.2404]"         
 #[3] "(72.2404,1958.629]"        "(1958.629,54176.3638]"    
 #[5] "(54176.3638,1468864.1897]"


 exp(as.data.frame(t(sapply(strsplit(Labs1, '[^-0-9.]+'), 
             function(x) as.numeric(x[-1])))))
 #           V1           V2
 #1 9.827359e-02 2.691234e+00
 #2 2.691234e+00 7.224044e+01
 #3 7.224044e+01 1.958629e+03
 #4 1.958629e+03 5.417636e+04
 #5 5.417636e+04 1.468864e+06
person akrun    schedule 29.07.2015
comment
Есть ли способ избежать использования sub для res, akrun и @Benjamin? - person MYaseen208; 29.07.2015
comment
@ MYaseen208 Я обновил параметры strsplit и gsubfn - person akrun; 29.07.2015
comment
@ MYaseen208 На основе предоставленного примера он дает ожидаемый результат, как вы в нем показали. В других случаях может быть немного иначе. - person akrun; 29.07.2015
comment
@ MYaseen208 Это потому, что мы не сопоставили часть - в обоих других решениях :-) - person akrun; 29.07.2015
comment
@ MYaseen208 Я изменил gsubfn, добавив -. Теперь он должен совпадать. Результаты, которые вы получили с e+ или e- при преобразовании, будут иметь такое же значение. - person akrun; 29.07.2015