Использование регулярного выражения в R для классификации данных - PullRequest
2 голосов
/ 21 февраля 2011

У меня есть файл с двумя столбцами, один имеет тип содержимого объектов HTTP, таких как text / html, application / rar и т. Д., А другой имеет размер в байтах.

Content Type                                     Size
video/x-flv                                       100
image/jpeg                                        150
text/html                                         160
application/octet-stream                          200  
application/x-shockwave-flash                     ...
text/plain
application/x-javascript
text/xml
text/css
text/html; charset=utf-8
application/x-javascript; charset=utf-8           ...

Как вы можете видеть, существует много вариантов одного и того же типа контента, таких как application/x-javascript и application/x-javascript; charset=utf-8 и так далее. Итак, я хотел бы создать еще один столбец, чтобы классифицировать их более обобщенно. Таким образом, эти два будут просто web/javascript и т. Д.

 Content Type                                      Size      Category
    video/x-flv                                       100       web/video
    image/jpeg                                        150       web/image
    text/html                                         160       web/html
    application/octet-stream                          200       web/binary
    application/x-shockwave-flash                     ...       web/flash
    text/plain                                                  web/plaintext
    application/x-javascript                                    web/javascript
    video/x-msvideo                                             web/video
    text/xml                                                    web/xml
    text/css                                                    web/css
    text/html; charset=utf-8                                    web/html
    video/quicktime                                             web/video
    application/x-javascript; charset=utf-8                     web/javascript

Как бы я достиг этого в R, и я полагаю, что для этого мне нужно использовать какие-то регулярные выражения?

Ответы [ 3 ]

3 голосов
/ 21 февраля 2011

Есть несколько способов упростить вашу переменную.Здесь я буду использовать пакет stringr для функций манипуляции со строками:

R> library(stringr)

Сначала скопируйте переменную типа контента в новую символьную переменную:

R> d <- data.frame(type=c("video/x-flv", "image/jpeg","video/x-msvideo", "application/x-javascript; charset=utf-8", "application/x-javascript"))
R> d$type2 <- as.character(d$type)

, которая просто дает вам:

                                     type                                   type2
1                             video/x-flv                             video/x-flv
2                              image/jpeg                              image/jpeg
3                         video/x-msvideo                         video/x-msvideo
4 application/x-javascript; charset=utf-8 application/x-javascript; charset=utf-8
5                application/x-javascript                application/x-javascript

Затем вы можете работать с новой переменной.Вы можете просто вручную заменить определенное значение типа другим:

R> d$type2[d$type2 == "video/x-flv"] <- "video"
R> d
                                     type                                   type2
1                             video/x-flv                                   video
2                              image/jpeg                              image/jpeg
3                         video/x-msvideo                         video/x-msvideo
4 application/x-javascript; charset=utf-8 application/x-javascript; charset=utf-8
5                application/x-javascript                application/x-javascript

Вы можете использовать сопоставление с регулярным выражением для замены всех совпадающих значений, например, "video":

R> d$type2[str_detect(d$type2, ".*video.*")] <- "video"
R> d
                                     type                                   type2
1                             video/x-flv                                   video
2                              image/jpeg                              image/jpeg
3                         video/x-msvideo                                   video
4 application/x-javascript; charset=utf-8 application/x-javascript; charset=utf-8
5                application/x-javascript                application/x-javascript

Или выможет использовать замену регулярного выражения для очистки определенных значений.Например, удалив все за ";"в типах контента:

R> d$type2 <- str_replace(d$type2, ";.*$", "")
R> d
                                     type                    type2
1                             video/x-flv                    video
2                              image/jpeg               image/jpeg
3                         video/x-msvideo                    video
4 application/x-javascript; charset=utf-8 application/x-javascript
5                application/x-javascript application/x-javascript

Будьте осторожны с порядком выполнения ваших инструкций, так как от этого сильно зависит ваш результат.

1 голос
/ 21 февраля 2011

Предположим, что DF - это наш фрейм данных.Определите регулярное выражение re для сопоставления интересующих строк, а затем используйте strapply в пакете gsubfn, чтобы извлечь их, добавив префикс "web/" к каждой.В операторе strapply мы преобразовали DF[[1]] в символ на случай, если это фактор, а не символьный вектор.Записи NULL не были сопоставлены, поэтому предположим, что они "web/binary".Наконец, разверните все вхождения от "plain" до "plaintext":

> library(gsubfn)
> re <- "(video|image|html|flash|plain|javascript|xml|css).*"
> short <- strapply(as.character(DF[[1]]), re, ~ paste("web", x, sep = "/"))
> DF$short <- sapply(short, function(x) if (is.null(x)) "web/binary" else x)
> DF$short <- sub("plain", "plaintext", DF$short)
> DF
                                   Content          short
1                              video/x-flv      web/video
2                               image/jpeg      web/image
3                                text/html       web/html
4                 application/octet-stream     web/binary
5            application/x-shockwave-flash      web/flash
6                               text/plain  web/plaintext
7                 application/x-javascript web/javascript
8                          video/x-msvideo      web/video
9                                 text/xml        web/xml
10                                text/css        web/css
11                text/html; charset=utf-8       web/html
12                         video/quicktime      web/video
13 application/x-javascript; charset=utf-8 web/javascript

Более подробная информация о пакете gsubfn в http://gsubfn.googlecode.com.

1 голос
/ 21 февраля 2011

Если бы вам пришлось делать это вручную, вы могли бы распределить свои факторы по соответствующим категориям.В этом примере я группирую первые 13 букв алфавита как «1», а вторую половину букв как «2».

> x <- as.factor(sample(letters, 100, replace = TRUE))
> x
  [1] d n p n k l a x c n v p l o u e z m y x t r q b l n y s s m d u l l a d k
 [38] t a p x s g w i p l b s o t b s h h v c b j o p h f j m v d r m x o d l e
 [75] l f y l u e w f e e o s w s m v a z q l a t f z x s
Levels: a b c d e f g h i j k l m n o p q r s t u v w x y z
> levels(x)
 [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x" "y" "z"
> levels(x) <- c(rep(1, 13), rep(2, 13))
> x
  [1] 1 2 2 2 1 1 1 2 1 2 2 2 1 2 2 1 2 1 2 2 2 2 2 1 1 2 2 2 2 1 1 2 1 1 1 1 1
 [38] 2 1 2 2 2 1 2 1 2 1 1 2 2 2 1 2 1 1 2 1 1 1 2 2 1 1 1 1 2 1 2 1 2 2 1 1 1
 [75] 1 1 2 1 2 1 2 1 1 1 2 2 2 2 1 2 1 2 2 1 1 2 1 2 2 2
Levels: 1 2
> levels(x)
[1] "1" "2"

Если ваш пример содержит (только) факторы, например:

"video/x-flv" "image/jpeg" "video/x-msvideo" "application/x-javascript; charset=utf-8"

... вы бы закодировали свои уровни так:

levels(obj) <- c("web/video", "web/image", "web/video", "web/javascript")
...