2011-11-28 5 views
20

문자열 문자열 (사람 이름)을 두 개의 열 (벡터)로 분할하고 싶습니다. 문제는 어떤 사람들에게는 '두 단어'라는 성이 있다는 것입니다. 이름과 성을 두 개의 열로 나누고 싶습니다. 나는 밑줄을 긋고 아래 코드를 사용하여 이름을 쓰지만 성은 나를 벗어난다. (포드는 함께 보존되어야하는 Pantera L의 "성"을 가지고있는 아이디어를 얻기 위해 아래의 샘플 세트에서 obs 29를보십시오)첫 번째 공백에서 문자열 분할

내가 지금까지 시도한 바는 무엇입니까?

x<-rownames(mtcars) 
unlist(strsplit(x, " .*")) 

내가 좋아하는보고를하고 싶은 것 : 당신이 패턴 및 그룹 매칭을 할 수 있다면

  MANUF  MAKE 
27   Porsche  914-2 
28   Lotus  Europa 
29   Ford  Pantera L 
30   Ferrari  Dino 
31   Maserati Bora 
32   Volvo  142E 

답변

25

정규 표현식 rexp은 문자열의 시작 부분에있는 단어, 선택적 공백, 그리고 나머지 문자열과 일치합니다. 괄호는 하위 참조 \\1\\2으로 액세스되는 하위 표현식입니다. 나를 위해

rexp <- "^(\\w+)\\s?(.*)$" 
y <- data.frame(MANUF=sub(rexp,"\\1",x), MAKE=sub(rexp,"\\2",x)) 
tail(y) 
#  MANUF  MAKE 
# 27 Porsche  914-2 
# 28 Lotus Europa 
# 29  Ford Pantera L 
# 30 Ferrari  Dino 
# 31 Maserati  Bora 
# 32 Volvo  142E 
+0

@ Joshua Ullrich Beautiful. 설명해 주셔서 감사합니다. –

0

, 나는 (안된) 이런 식으로 뭔가를 시도 할 것 :

\s+(.*)\s+(.*) 
+4

그냥 정규식이 R에서 조금 다른 방식으로 작동한다는 것을 알고 있습니다. 최소한 오류를 피하기 위해 각각의 앞에 \를 추가해야합니다. – joran

0

[^\s]+을 검색하면 효과가 있다고 생각합니다. 테스트되지 않았습니다.

17

reshape2 패키지 해들리의 colsplit 기능은 이러한 목적에 가장 직관적이다. Joshua의 방식은 정규식 (즉, 정규 표현식을 사용할 수있는 곳이라면 어디에서나 사용될 수있다)과 유연하다 (명세를 바꾸고 싶다면);

library(reshape2) 
y <- colsplit(x," ",c("MANUF","MAKE")) 
tail(y) 
#  MANUF  MAKE 
#27 Porsche  914-2 
#28 Lotus Europa 
#29  Ford Pantera L 
#30 Ferrari  Dino 
#31 Maserati  Bora 
#32 Volvo  142E 
+0

아주 좋은 열 분할 사용. 감사. –

+0

+1 정말 흥미 롭습니다. 왜냐하면'colsplit'은이 경우에 3 열 이상을 반환 할 것이라고 가정했기 때문입니다. 내가 얼마나 틀렸어. – Andrie

7

그러나 그 일을하는 또 다른 방법 :하지만 colsplit 기능이 특정 설정에 완벽하게 적합 분할을 처리 할 stringr에서

str_split,하지만 같은 (다른 형태의리스트를 돌려줍니다 strsplit). 올바른 양식으로 조작하는 것은 간단합니다. 해들리는 str_split_fixed으로, 코멘트에 언급 한 바와 같이

library(stringr) 
split_x <- str_split(x, " ", 2) 
(y <- data.frame(
    MANUF = sapply(split_x, head, n = 1), 
    MAKE = sapply(split_x, tail, n = 1) 
)) 

또는.

1)를 strsplit :

y <- as.data.frame(str_split_fixed(x, " ", 2)) 
colnames(y) <- c("MANUF", "MAKE") 
y 
+0

@ 리치 (Hadley Wickham) 패키지를 통해 또 다른 솔루션을 제공합니다. 감사합니다. –

+2

'str_split_fixed '를 사용하는 것이 더 낫겠습니까? – hadley

+1

'colsplit'은'str_split_fixed'를 사용하기 때문에이 답변 + hadley의 의견은'colsplit' 해결책과 관련이 있습니다. –

11

여기서 두 가지 방법이다. 이 접근법은 R의 핵심에있는 함수 만 사용하며 복잡한 정규식은 사용하지 않습니다. 세미콜론 제 공간을 장착 2 열의 행렬로 다음, strsplit 세미콜론 온 rbind을 (sub하지gsub 사용)

mat <- do.call("rbind", strsplit(sub(" ", ";", x), ";")) 
colnames(mat) <- c("MANUF", "MAKE") 

2) strapply gsubfn 패키지 여기서으로는 하나이다 gsubfn 패키지에서 strapply을 사용하는 - 라이너. 정규 표현식의 두 개의 괄호로 묶은 부분은 각각 원하는 첫 번째와 두 번째 열을 캡처하고 함수 (수식 표기법에 지정 - 이는 function(x, y) c(MANUF = x, MAKE = y)을 지정하는 것과 동일 함)를 가져 와서 이름을 추가합니다.simplify=rbind 인수는 이전 솔루션 에서처럼 행렬로 변환하는 데 사용됩니다.

library(gsubfn) 
mat <- strapply(x, "(\\S+)\\s+(.*)", ~ c(MANUF = x, MAKE = y), simplify = rbind) 

참고 : "character" 행렬 mat가 반환 어느 경우. "character" 컬럼의 데이터 프레임을 원하는 경우 다음이 추가 : "factor" 열이 원하는 경우

DF <- as.data.frame(mat, stringsAsFactors = FALSE) 

stringsAsFactors 인수를 생략합니다.

+0

방금 ​​여기를 다시 확인했습니다. 나는 실제로 당신의 # 1 해결책을 가장 좋아하는 어떤 것을 공급해도 좋았습니다. 나중에 반품 해 주셔서 고맙고 미안합니다. –