вторник, 16 февраля 2016 г.

Простейший пример метапрограммирования в R

Вконтактике был задан любопытный вопрос, для которого удалось придумать относительно нетривиальное решение (по крайней мере, более интересное, чем очевидный вариант парсинга при помощи регулярных выражений). Пусть есть вектор из строк, и каждая строка, если ее выполнить как выражение, могла бы дать нам какой-то полезный результат (например, создать объект). Как же заставить R обработать строку в качестве выражения? Вот минимальный пример, который демонстрирует работу необходимых для этого функций eval() и parse().

> a <- 'list(uid = 23425, name = "qwerty")'
> b <- 'list(uid = 23225, name = "name")'
> vvv <- c(a, b, a, b)
> vvv
[1] "list(uid = 23425, name = \"qwerty\")" "list(uid = 23225, name = \"name\")"  
[3] "list(uid = 23425, name = \"qwerty\")" "list(uid = 23225, name = \"name\")"  
> res <- vapply(X = vvv, FUN = function(x) eval(parse(text = x)), 
+               FUN.VALUE = list(uid = 0, name = 0))
> res <- t(res)
> as.data.frame(res, row.names = 1:dim(res)[1])
    uid   name
1 23425 qwerty
2 23225   name
3 23425 qwerty
4 23225   name

Больше информации на тему ищите в http://adv-r.had.co.nz/Expressions.html