2017-10-05 4 views
0

여러 행으로 구성된 데이터 프레임이 있는데, 모든 행을 벡터의 요소를 기반으로 두 개의 구성 요소로 분리하고 싶습니다 (본질적으로 벡터로 strsplit 실행). R.문자열로 벡터가있는 데이터 프레임을 RDM으로 분할하는 문자열

dataframe (하나의 열)의 '패턴')로 다음과 같은 :

 [,1]     
[1,] "apple please fuji" 
[2,] "pear help name"  
[3,] "banana me mango" 

내 패턴 벡터는 다음과 같이 수있는 반면 : v <- c("please", "help", "me").

가능하면, 내가 할 내 출력을 싶습니다

df$name    df$part1 df$split df$part2 
"apple please fuji" "apple" "please" "fuji" 
"pear help name" "pear"  "help" "name" 
"banana me mango" "banana" "me"  "mango" 

내가 벡터에 따라 구성 요소를 분리 할 수있는 단계 간에서하지만, 만약 거기에 어떤 도움을 주셔서 감사합니다 것입니다 이것을 데이터 프레임에 넣는 더 쉬운 방법입니다. 정말 고맙습니다!

+0

를 반환 ("빨간 사과", "제발", "후지") '가 될 C 초래 '? – zx8754

+0

@ zx8754, 그래, 그게 내가 원하는거야! 세 가지 범주 (단어 수에 관계없이)를 분리하고 싶습니다. 나누기 문자열, 나누기 문자열 및 나누기 문자열 뒤에. 감사! – maria

답변

2

여기 기재 R. 두 방법 문자 벡터

시작됩니다 또한

text <- c("apple please fuji", "pear help name", "banana me mango") 

(편의상) 원하는 변수 이름

varNames <- c("name", "part1", "split", "part2") 
대안으로

regexecregmatches를 사용하여


, 당신은이 데이터 세트를 구성 할 수 regmatches/regexec 조합으로 정규 표현식을 사용할 수 있습니다.

먼저 v에서 정규 표현식을 paste으로 작성하십시오.이

   name part1 split part2 
1 apple please fuji apple please fuji 
2 pear help name pear help name 
3 banana me mango banana  me mango 

strsplitdo.call

우선하여 상기와 같은 반환

myRegex <- paste0("^(.*) +(", paste(v, collapse="|"), ") +(.*)$") 
myRegex 
[1] "^(.*)(please|help|me)(.*)$" 

setNames(do.call(rbind.data.frame, regmatches(text, regexec(myRegex, text))), varNames) 

, V, 각 소자 분리

tmp <- do.call(strsplit, list(text, split=v)) 
tmp 
[[1]] 
[1] "apple " " fuji" 

[[2]] 
[1] "pear " " name" 

[[3]] 
[1] "banana " " mango" 

이제 rbind.data.frame 두 번째 열을 삭제하고 split.filename 변수 cbind을 반환 한 다음 setNames과 함께 이름을 추가합니다. 첫 번째 행 "빨간 사과하십시오 후지"``라면

setNames(cbind(text, do.call(rbind.data.frame, tmp), v)[c(1, 2, 4, 2)], varNames) 

   name part1 split part2 
1 apple please fuji apple please apple 
2 pear help name pear help pear 
3 banana me mango banana  me banana 

1

이 솔루션은 v의 요소 수가 데이터 프레임의 행 수와 동일한 것으로 가정합니다. tidyr 패키지의 separate을 사용하여 part1part2을 만들 수 있습니다.

library(tidyverse) 
df <- tibble(name = c("apple please fuji", "pear help name", "banana me mango")) 
v <- c("please", "help", "me") 

df %>% 
    separate(name, c("part1", "part2"), v, remove = FALSE) %>% 
    add_column(split = v, .before = "part2") 
#> # A tibble: 3 x 4 
#>    name part1 split part2 
#>    <chr> <chr> <chr> <chr> 
#> 1 apple please fuji apple please fuji 
#> 2 pear help name pear help name 
#> 3 banana me mango banana  me mango 

당신이 시도하려는 한 다음 분리하기 전에 먼저 하나의 패턴으로 v를 붙여 시도 할 수 v의 모든 요소를 사용하여 각 행을 분할합니다. 이런 식으로하면 효과가 있다고 생각합니다.

library(tidyverse) 
library(stringr) 
p <- paste0("\\b(?:", paste(v, collapse = "|"), ")\\b") 
df %>% 
    separate(name, c("part1", "part2"), p, remove = FALSE) %>% 
    mutate(split = str_extract(name, p)) %>% 
    select(name, part1, split, part2) 
#> # A tibble: 3 x 4 
#>    name part1 split part2 
#>    <chr> <chr> <chr> <chr> 
#> 1 apple please fuji apple please fuji 
#> 2 pear help name pear help name 
#> 3 banana me mango banana  me mango 
0
# Creating creating the df 
name <- c("apple please fuji","pear help name","banana me mango") 

# as.data.frame 
df <- as.data.frame(name, stringsAsFactors = F) 
# Initialize empty data frame. 
df_n <- data.frame() 
# Loop through the original rows of the df. 
for(i in 1:nrow(df)){ 
    for(j in 1:nrow(df)){ 
    o <- strsplit(df$name, " ")[[i]][j] 
    } 
} 
# rename and assign new df (df_n) changes to original df. 
df$part1 <- df_n$V1 
df$part2 <- df_n$V2 
df$part3 <- df_n$V3 

print(df) 
+0

감사합니다. For 루프는 상당히 느리고 데이터 프레임 크기가 상당히 크기 때문에 불행히도 이러한 작업은 저에게 효과적이지 않습니다. 벡터화하는 방법에 대한 아이디어가 있습니까? 고맙습니다! – maria

관련 문제