Эффективный способ сложить все числа, кроме тех, которые сопровождают I, с помощью mclapply

У меня такой вектор:

my.vector = c("4M1D5M15I1D10M", "3M", "4M2I3D")

И я хотел бы преобразовать его в следующий вектор:

my.result = c("21N", "3N", "7N")

Логика таких результатов следующая: для "4M1D5M15I1D10M" я добавил все числа, кроме тех, которые предшествуют символу "I", то есть 4 + 1 + 5 + 1 + 10 = 21 (я не добавил 15, потому что он предшествует символу "I"). "I"), а затем вставьте N сразу после 21, превратившись в "21N".

То же самое для "3M", здесь нет символа "I", поэтому он просто становится "3N"; и то же самое для последнего, 4 + 3 = 7 (я не добавил 2, потому что он предшествует "I"), становится "7N".

Обратите внимание, что my.vector очень большой, поэтому я хочу использовать параллельные возможности сервера HPC с помощью mclapply. В идеале я бы запустил что-то вроде этого, чтобы получить свой результат:

my.result = unlist(mclapply(my.vector, my.adding.function, mc.cores = ncores))

Для определения моей функции я попробовал следующее:

my.adding.function <- function(x)
{
   tmp = unlist(strsplit(x, "\\d+I"))
   tmp2 = unlist(strsplit(tmp, "M|D|S|N"))
   tmp3 = sum(as.numeric(tmp2))
   return(paste(tmp3, "N",sep=""))
}

Хотя не уверен в эффективности такой функции ...


person Dnaiel    schedule 28.09.2013    source источник
comment
@Gsee, хорошая мысль, положи это туда.   -  person Dnaiel    schedule 28.09.2013
comment
@Gsee, в основном, я пытаюсь научиться работать в R, чтобы операции с огромными данными не занимали слишком много времени. У меня есть реализованный код, но когда я запускаю его, это занимает вечность и никогда не заканчивается, поэтому я пытаюсь оптимизировать каждый шаг, таким образом, mclapply и т.д ... Я могу написать свои собственные функции, которые делают большую часть того, что я хочу, но они в конечном итоге будут довольно медленными.   -  person Dnaiel    schedule 28.09.2013
comment
Маловероятно, что лучшим решением будет использовать mclapply для каждой небольшой операции в вашем коде, потому что есть накладные расходы, связанные со сбором результатов. Вам, вероятно, будет лучше векторизовать как можно больше и использовать mclapply на более крупных логических объектах, но я просто предполагаю, поскольку вы показываете нам только один крошечный фрагмент своего проекта за раз.   -  person GSee    schedule 28.09.2013
comment
@Gsee, это имеет смысл, это хороший совет, теперь я печатаю отметки времени после каждой операции, так что это даст мне хорошее представление о узких местах. Кстати, накладные расходы mclapply намного лучше, чем foreach и parLapply для небольших операций.   -  person Dnaiel    schedule 28.09.2013
comment
@Gsee, я бы с удовольствием поставил весь свой код для оптимизации, но я стараюсь быть внимательным. Было бы неплохо, если бы была сессия проверки кода :-), просто выдавая желаемое за действительное ...   -  person Dnaiel    schedule 28.09.2013
comment
Вам необходимо профилировать свой код. См. stackoverflow.com/a/2075404/967840, stat.berkeley.edu/~nolan/stat133/Fall05/lectures/ или stackoverflow.com/questions/3650862/   -  person GSee    schedule 28.09.2013
comment
@Gsee, вау, это отличный совет, большое спасибо!   -  person Dnaiel    schedule 28.09.2013


Ответы (1)


Вот одно решение без mclapply, проверьте, возможно ли это:

L <- regmatches(my.vector, gregexpr("(\\d+)(?=[A-HJ-Z])", my.vector, perl=TRUE))
sapply(L, function(x)paste0(sum(as.numeric(x)),"N"))
person Ferdinand.kraft    schedule 28.09.2013
comment
вы можете заменить sapply на mclapply;) - person GSee; 28.09.2013