2014-01-26 10 views
0

Структура набора данных:Извлечение символов из строки

> str(trainData) 
'data.frame': 891 obs. of 13 variables: 
$ PassengerId: int 1 2 3 4 5 6 7 8 9 10 ... 
$ Survived : Factor w/ 2 levels "No","Yes": 1 2 2 2 1 1 1 1 2 2 ... 
$ Pclass  : Factor w/ 3 levels "1st","2nd","3rd": 3 1 3 1 3 3 1 3 3 2 ... 
$ Name  : chr "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ... 
$ Sex  : Factor w/ 2 levels "Male","Female": 1 2 2 2 1 1 1 1 2 2 ... 
$ Age  : num 22 38 26 35 35 NA 54 2 27 14 ... 
$ SibSp  : int 1 1 0 1 0 0 0 3 0 1 ... 
$ Parch  : int 0 0 0 0 0 0 0 1 2 0 ... 
$ Ticket  : int NA NA NA 113803 373450 330877 17463 349909 347742 237736 ... 
$ Fare  : num 7.25 71.28 7.92 53.1 8.05 ... 
$ Cabin  : chr "" "C85" "" "C123" ... 
$ Embarked : chr "S" "C" "S" "S" ... 
$ Area  : Factor w/ 9 levels "","A","B","C",..: 1 4 1 4 1 1 6 1 1 1 ... 

Я хочу, чтобы создать новый столбец в кадре данных для хранения в виде адреса, содержащегося в переменной Name. Для этого мне нужно извлечь строки «Mr», «Mrs» и т. Д. И сохранить их в новом векторе. Я решил решить эту проблему следующим образом.

vec <- vector() 

for (i in 1 : nrow(trainData)) { 
    if (grep("Mr\\.", trainData[i, "Name"]) == 1) {vec[i] <- "Mr"} 
    else if (grep("Miss\\.", trainData[i, "Name"]) == 1) {vec[i] <- "Miss"} 
    else if (grep("Mrs\\.", trainData[i, "Name"]) == 1) {vec[i] <- "Mrs"} 
    else if (grep("Don\\.", trainData[i, "Name"]) == 1) {vec[i] <- "Don"} 
    else if (grep("Master\\.", trainData[i, "Name"]) == 1) {vec[i] <- "Master"} 
    else {vec[i] <- "Boh"} 
} 

.. и после этого использовать функцию cbind связать существующий фрейм данных с новым столбцом FormOfAddress. Я не тестировал следующие две строки кода, потому что получаю сообщение об ошибке из предыдущего фрагмента.

trainData <- as.data.frame(cbind(trainData, vec)) 
names(trainData)[length(trainData)] <- "FormOfAddress" 

В основном я застрял в этот момент ..

> vec <- vector() 
> for (i in 1 : nrow(trainData)) { 
+ if (grep("Mr\\.", trainData[i, c("Name")]) == 1) {vec[i] <- "Mr"} 
+ else if (grep("Miss\\.", trainData[i, c("Name")]) == 1) {vec[i] <- "Miss"} 
+ else if (grep("Mrs\\.", trainData[i, c("Name")]) == 1) {vec[i] <- "Mrs"} 
+ else if (grep("Don\\.", trainData[i, c("Name")]) == 1) {vec[i] <- "Don"} 
+ else if (grep("Master\\.", trainData[i, c("Name")]) == 1) {vec[i] <- "Master"} 
+ else {vec[i] <- "Boh"; next} 
+ } 
Error in if (grep("Mr\\.", trainData[i, c("Name")]) == 1) { : 
    argument is of length zero 

Первая часть, если заявление выглядит прямо ко мне. Когда строка Mr. содержится в имени, она возвращает TRUE. Также вторая часть выглядит отлично (по крайней мере, в первом цикле) и записывает строку Mr на вектор vec. Проблема во втором цикле, я думаю, но я не могу найти способ заставить его работать.

+3

Вы хотите 'grepl', если хотите вернуть логический. 'grep' возвращает индексы совпадений, поэтому, если нет совпадения, результатом' grep' будет вектор длины 0. Посмотрите на '? Gsub' для более простого способа сделать это без цикла for –

+0

Спасибо Джейк,' grepl' отлично работает. Завтра я посмотрю на 'gsub', чтобы узнать, как решить проблему без использования инструкции for loop. – Gianluca

+0

Я добавил ответ с помощью решения 'gsub'. Надеюсь, что это поможет –

ответ

0
trainData$Name 

## [1] "Braund, Mr. Owen Harris"        
## [2] "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" 
## [3] "Heikkinen, Miss. Laina"        
## [4] "Futrelle, Mrs. Jacques Heath (Lily May Peel)"  
## [5] "tt"             
## [6] "Mr. Jones"           

for (x in trainData$Name) { 
    print(grep("Mr\\.", x)) 
    print(grepl("Mr\\.", x)); 
} 

## [1] 1 
## [1] TRUE 
## integer(0) 
## [1] FALSE 
## integer(0) 
## [1] FALSE 
## integer(0) 
## [1] FALSE 
## integer(0) 
## [1] FALSE 
## [1] 1 
## [1] TRUE 

## Doing it without a loop. 
## You might have to come up with a different 
## regex here depending on the rest of your data 
vec <- gsub("^([^,]+,)?([^.]+).*", "\\2", trainData$Name) 
## [1] "Mr" "Mrs" "Miss" "Mrs" "tt" "Mr" 
vec <- ifelse(vec == trainData$Name, "Boh", vec) 
## [1] "Mr" "Mrs" "Miss" "Mrs" "Boh" "Mr" 
Смежные вопросы