2017-12-21 14 views
2

에서 여러 단어의 정확한 일치를 기반으로 새 열을 버리는 : 나는 일반적인 물고기 코드/이름으로 채워 열을 사용할 필요가내가 데이터 프레임이 문자열

df <- data.frame(
    Otherspp = c("suck SD", "BT", "SD RS", "RSS"), 
    Dominantspp = c("OM", "OM", "RSS", "CH"), 
    Commonspp = c(" ", " ", " ", "OM"), 
    Rarespp = c(" ", " ", "SD", "NP"), 
    NP = rep("northern pikeminnow|NORTHERN PIKEMINNOW|np|NP|npm|NPM", 4), 
    OM = rep("steelhead|STEELHEAD|rainbow trout|RAINBOW TROUT|st|ST|rb|RB|om|OM", 4), 
    RSS = rep("redside shiner|REDSIDE SHINER|rs|RS|rss|RSS", 4), 
    suck = rep("suckers|SUCKERS|sucker|SUCKER|suck|SUCK|su|SU|ss|SS", 4) 
) 

을 (NP, OM, RSS, 빨아) 첫 번째 네 열의 표현식을 평가하고 표현식이 정확히 충족되면 해당 열을 기반으로 1/0을 출력합니다. 아래에있는 코드는 전체 단어 (일부만)와 일치하지 않으며 잘못된 데이터를 제공합니다 (아래에서 결과를보십시오).

df %>% 
    rowwise() %>% 
    transmute_at(vars(NP, OM, RSS, suck), 
       funs(case_when(
       grepl(., Dominantspp) ~ "1", 
       grepl(., Commonspp) ~ "1", 
       grepl(., Rarespp) ~ "1", 
       grepl(., Otherspp) ~ "1", 
       TRUE ~ "0"))) %>% 
    ungroup() 

결과 : 행 3에서 "suck"및 "RSS"는 모두 "1"을 수신합니다.

# A tibble: 4 x 4 
    NP OM RSS suck 
    <chr> <chr> <chr> <chr> 
1  0  1  0  1 
2  0  1  0  0 
3  0  0  1  1 
4  1  1  1  1 

원하는 출력 :

NP OM RSS suck 
1 0 1 0 1 
2 0 1 0 0 
3 0 0 1 0 
4 1 1 1 0 
+0

위의 테스트 케이스에 대해 예상 한 올바른 결과를 제공 할 수 있습니까? –

+0

분명히하기 위해 네 개의 열 (anypp, Dominantspp 등)이 정규식과 일치 할 때 해당 열에 0 또는 1을 입력 하시겠습니까? –

+0

원하는 출력 (@StuartAllen)으로 게시물을 업데이트했습니다. 나는 그 종의 "존재"를 나타내는 1을, 결석의 경우 0을 (@David Robinson) 원합니다. – LAB

답변

2

\\b와 함께, 귀하의 정규 표현식에 각각의 시작과 끝 단어 경계를 추가하기 위해 같은 방법이다 사용하여 문제를 해결하는 가장 빠른 방법 :

df <- data.frame(
    Otherspp = c("suck SD", "BT", "SD RS", "RSS"), 
    Dominantspp = c("OM", "OM", "RSS", "CH"), 
    Commonspp = c(" ", " ", " ", "OM"), 
    Rarespp = c(" ", " ", "SD", "NP"), 
    NP = rep("\\b(northern pikeminnow|NORTHERN PIKEMINNOW|np|NP|npm|NPM)\\b", 4), 
    OM = rep("\\b(steelhead|STEELHEAD|rainbow trout|RAINBOW TROUT|st|ST|rb|RB|om|OM\\b)", 4), 
    RSS = rep("\\b(redside shiner|REDSIDE SHINER|rs|RS|rss|RSS)\\b", 4), 
    suck = rep("\\b(suckers|SUCKERS|sucker|SUCKER|suck|SUCK|su|SU|ss|SS)\\b", 4), 
    stringsAsFactors = FALSE 
) 

이렇게하면 일반 표현식이 전체 단어와 일치하기 때문에 이후의 솔루션 작업이 가능합니다.


은 ( rowwise() 거의 오늘 권장되지 않으며,이 방법은 많은 물고기 코드에 잘 확장되지 않습니다) 나는이 반드시 문제를 접근하는 방법이라고 생각하지 않는다,라고 말했다 가졌어요. 난 당신이 행과 코드의 조합 당 하나의 행으로, 단정 한 형식으로 표준화 경우이 데이터 작업을 쉽게 시간을 거라고 생각 :

library(tidyr) 
library(tidytext) 

row_codes <- df %>% 
    select(Otherspp:Rarespp) %>% 
    mutate(row = row_number()) %>% 
    gather(type, codes, -row) %>% 
    unnest_tokens(code, codes, token = "regex", pattern = " ") 

될 것이다 :

row  type code 
1 1 Dominantspp om 
2 1 Otherspp suck 
3 1 Otherspp sd 
4 2 Dominantspp om 
5 2 Otherspp bt 
6 3 Dominantspp rss 
7 3 Otherspp sd 
8 3 Otherspp rs 
9 3  Rarespp sd 
10 4 Commonspp om 
11 4 Dominantspp ch 
12 4 Otherspp rss 
13 4  Rarespp np 

이 시점에서 코드는 작업하기가 훨씬 쉽습니다 (정규 표현식이 더 이상 필요하지 않음). 예를 들어 inner_join을 물고기 코드 테이블에 표시 할 수 있습니다.

+0

이 접근법을 사용하여 더 큰 데이터 세트에서 작동하는지 확인해 보겠습니다. – LAB