У меня есть вопрос о ссылках на объекты путем получения имени объекта из переменной.
SETUP
library(data.table)
object <- c("one", "two", "three")
attributes <- c("green, blue, red", "red", "blue, orange")
DT <- data.table(object,attributes) ; DT
object attributes
1: one green, blue, red
2: two red
3: three blue, orange
Это базовая установка, которая у меня есть (упрощенные данные). У меня есть объекты с именами, и каждому назначены атрибуты. Атрибуты находятся в исходном наборе данных в виде строк, разделенных запятыми, в одной ячейке таблицы. Атрибуты берутся из конечного известного списка атрибутов. В этом примере я использую цвета. Мне нужно уметь находить объекты по атрибутам. Итак, выделите все объекты с красным атрибутом. (в реальном примере есть 20k объектов и ~ 200 атрибутов) После получения необработанных данных и создания таблицы data.table я хочу создать столбцы флагов для всех возможных атрибутов, чтобы облегчить поиск / подустановку. Итак, это…
DT[, isRed := FALSE]
DT[, isGreen := FALSE]
DT[, isBlue := FALSE]
DT[, isOrange := FALSE]
DT
object attributes isRed isGreen isBlue isOrange
1: one green, blue, red FALSE FALSE FALSE FALSE
2: two red FALSE FALSE FALSE FALSE
3: three blue, orange FALSE FALSE FALSE FALSE
Это создает мою базовую таблицу data.table, все столбцы флагов находятся на своих местах и перед обработкой установлено FALSE.
Обработка заключается в получении строки атрибута, синтаксическом анализе отдельные атрибуты и соответствующим образом установите флаг. Это то, что я делаю…
# take the first object, parse the attributes into a data.table
split.attributes <-
str_split(DT[object == "one", attributes], ",", n = Inf) %>%
transpose() %>%
data.table()
split.attributes
.
1: green
2: blue
3: red
# format the attributes with initial Uppercase, and update the data.table
# ignore the extraneous string manipulates (like "\\s") in the real world example
# the attributes are sometimes two word strings that are then a
# single flag name, i.e., "blue green" -> "BlueGreen"
split.attributes <- split.attributes[,.] %>%
str_to_title() %>%
str_remove("\\s") %>%
as.list() %>%
data.table()
split.attributes
.
1: Green
2: Blue
3: Red
У меня уже есть все имена столбцов флагов в форме «is», то есть «isRed», поэтому конвертируйте data.table…
# paste "is" in front of the attribute and change the column name to avoid referring to "." later
split.attributes[, col.names := paste0("is",.)]
split.attributes
. col.names
1: Green isGreen
2: Blue isBlue
3: Red isRed
# then remove the extraneous column
split.attributes[, . := NULL]
split.attributes
col.names
1: isGreen
2: isBlue
3: isRed
Теперь у меня есть набор имен флагов (которые соответствуют фактическим именам столбцов) для первого объекта в моей исходной таблице данных, и я хочу присвоить этим флагам новые значения (ИСТИНА). Я хочу вызвать значение из split.attributes [1] и использовать его как имя столбца в DT. Я знаю один способ сделать это ...
eval(parse( text = (paste0("DT[1, ", eval(split.attributes[i]), " := TRUE]"))))
DT
object attributes isRed isGreen isBlue isOrange
1: one green, blue, red FALSE TRUE FALSE FALSE
2: two red FALSE FALSE FALSE FALSE
3: three blue, orange FALSE FALSE FALSE FALSE
И мой единственный флаг теперь ИСТИНА, поэтому мы знаем, что object :: one - это "isGreen" :: ИСТИНА. Конечно, с помощью цикла я могу установить все необходимые флаги для всех объектов. Я видел много конкретных c решений, но все они следуют основной идее c; превратите переменную в строку, объедините эту строку с другими строками, необходимыми для построения вашего выражения, а затем оцените всю строку как выражение.
ВОПРОС
Есть ли лучший способ, чем, "eval (parse (text = (paste0 (" DT [1, ", eval (split.attributes [i]),": = TRUE] "))))"?
На мой взгляд, это обычная проблема (или, может быть, мой личный проект уникален в этом отношении), поэтому я чувствую, что вы должны уметь делать что-то вроде:
DT [1, ", get_the_variable_value_and_add_as_part_of_a_function ( split.attributes [i] ) ,": = TRUE]
Что затем создаст базовое выражение, которое вы хотите, и то, что отправляется в R:
DT [1, isGreen: = TRUE] (как выражение, которое необходимо оценить)
Красиво и аккуратно, без суеты, без многоуровневых функций.
ПРИМЕЧАНИЕ: Я понимаю, что могу создать свою собственную функцию для этого, но то, что я спрашиваю, это «он уже существует, а я просто не нашел его?». Я просто пытаюсь понять, знает ли кто-нибудь то, чего я не знаю, что могло бы облегчить мою жизнь. СПАСИБО.