2013-03-07 2 views
4

Я не могу найти элегантный способ достижения этого, пожалуйста, помогите.разобрать строку, установить ее как факторный столбец в R data.table

У меня есть DT data.table:

name,value 
"lorem pear ipsum",4 
"apple ipsum lorem",2 
"lorem ipsum plum",6 

И на основе списка Fruits <- c("pear", "apple", "plum") Я хотел бы создать столбец типа фактор.

name,value,factor 
"lorem pear ipsum",4,"pear" 
"apple ipsum lorem",2,"apple" 
"lorem ipsum plum",6,"plum" 

Я предполагаю, что это простой, но я вроде застрял, это то, как далеко я получил:

DT[grep("apple", name, ignore.case=TRUE), factor := as.factor("apple")]

Спасибо заранее.

+0

Я думаю, мне нужно заменить 'as.factor («Яблоко»)' часть с изготовленный под заказ функция. –

ответ

6

Вы можете векторизовать это, используя регулярные выражения, например. с помощью gsub():

Настройка данных:

strings <- c("lorem pear ipsum", "apple ipsum lorem", "lorem ipsum plum") 
fruit <- c("pear", "apple", "plum") 

Теперь создать регулярное выражение

ptn <- paste0(".*(", paste(fruit, collapse="|"), ").*") 
gsub(ptn, "\\1", strings) 
[1] "pear" "apple" "plum" 

Регулярное выражение работает путем разделения каждого поискового элемента с |, внедренный внутри скобок :

ptn 
[1] ".*(pear|apple|plum).*" 

Для этого в таблице данных, в соответствии с ваш вопрос, то так просто, как:

library(data.table) 
DT <- data.table(name=strings, value=c(4, 2, 6)) 
DT[, factor:=gsub(ptn, "\\1", strings)] 
DT 

       name value factor 
1: lorem pear ipsum  4 pear 
2: apple ipsum lorem  2 apple 
3: lorem ipsum plum  6 plum 
+0

(+1) мой последний голос за день. аккуратный трюк. – Arun

+0

красивый, спасибо –

5

Я не знаю, если есть более «data.table» способ сделать это, но вы можете попробовать это:

DT[, factor := sapply(Fruits, function(x) Fruits[grep(x, name, ignore.case=TRUE)])] 
DT 
#     name value factor 
# 1: lorem pear ipsum  4 pear 
# 2: apple ipsum lorem  2 apple 
# 3: lorem ipsum plum  6 plum 
+1

(+1) Это, по сути, не типичная проблема 'data.table'. – Arun

+0

Это может быть я, но этот код заполняет столбец «DT $ factor» длинными списками DT, такими как 'c (NA, NA,« pear », NA,« apple », ...)'. Я расследую дальше, я уверен, что ваш намек (sapply) приведет меня к решению. –

+0

@ NyitraiLőrinc, я подозреваю, что ваш пример мини-данных не точно отражает проблему, которую вы пытаетесь решить. – A5C1D2H2I1M1N2O1R2T1

2

Вот мой закодированы решение. Жесткая часть получает строку со строкой от regex. Лучшее общее решение (которое находит все, что соответствует любому регулярному выражению), я знаю, что это комбинация regexec и regmatches (см. Ниже).

# Create the data frame 
name <- c("lorem pear ipsum", "apple ipsum lorem", "lorem ipsum plum") 
value <- c(4,2,6) 
DT <- data.frame(name=name, value=value, stringsAsFactors=FALSE) 

# Create the regular expression 
Fruits <- c("pear", "apple", "plum") 
myRegEx <- paste(Fruits, collapse = "|") 

# Find the matches 
r <- regexec(myRegEx, DT$name, ignore.case = TRUE) 
matches <- regmatches(DT$name, r) 

# Extract the matches, convert to factors 
factor <- sapply(matches, function(x) as.factor(x[[1]])) 

# Add to data frame 
DT$factor <- factor 

Это, вероятно, более длительное решение, чем вы хотели.

Смежные вопросы