2017-11-17 16 views
0

1500 개의 관측치와 130 개의 변수가있는 dt.train2 데이터 세트가 있습니다. 그 중 하나는 languages이며 내가 속성 english에 대한 1, 2french를 들어, 3spanish과 다른 것을위한 0 제공하는 ifelse 문자열을 만들 english, french, arabic ...여러 카테고리의 조건이있는 R의 Ifelse

수 있습니다. 나는 그것을 어떻게하는지 모른다.

dt.train2[, language_string := ifelse(language == "english", 
             1, 
             ifelse(language == "french", 
              2, 
              ifelse(language == "spanish",3)] 

저는 이것을 판매에 대한 선형 모델을 실행하는 데 사용하고 있습니다.

+0

, 3, 0) ', 당신은 **', 0' **이 필요합니다. – Gregor

+1

이것은 언어 효과가 무엇이든간에 프랑스 효과가 영어 효과의 2 배, 스페인 효과가 영어 효과의 3 배라고 생각하지 않는 한 선형 모델을 준비하는 끔찍한 방법처럼 보입니다. – Gregor

+1

나는 테이블을 만들고 업데이트 작업을 수행한다고 말하고 싶습니다. https://stackoverflow.com/questions/42587214/substitute-dt1-x-with-dt2-y-when-dt1-x-and-dt2-x-match -in-r – Frank

답변

0

확인이 :

t <- 'es' 
tt <- (if (t == 'en') 1 else if (t == 'fr') {2} else if (t == 'es') 3 else 0) 
tt 
[1] 0 

당신이 다음 dataframe 마음에 적용 할 수 있습니다 :이 선형 모델 인 경우, 그것은 나쁜 방법이라고 나는이 의견에 동의

df <- data.frame(l=c('en', 'fr', 'es', 'sthelse')) 
df$lnum <- sapply(df$l, function(t){(if (t == 'en') 1 else if (t == 'fr') {2} else if (t == 'es') 3 else 0)}) 
df 
     l lnum 
1  en 1 
2  fr 2 
3  es 3 
4 sthelse 0 
+0

이것을 대수적으로 쓸 수도 있는데,'(t == "en") + 2 * (t == "fr") + 3 * (t == "es")'이므로 벡터화됩니다. – Frank

+0

멋진 아이디어입니다! –

+0

토론 된 downvoting (하지 않았다),하지만 un-vectorized 방법은 정말 끔찍한, 심지어 수백 줄에 눈에 띄게 느리게됩니다. 그리고'unlist (lapply())'는 지나치게 복잡합니다. 만약 당신이 그렇게하려고한다면'sapply'를 사용하십시오. 그러나 벡터화 된'ifelse()'(또는 Frank의 똑똑한 벡터화 된 솔루션)가 훨씬 낫습니다. – Gregor

1

을 그것에 대해 갈 것입니다. 언어를 예측 변수로 주장한다면 일련의 더미 변수를 만드는 것이 더 좋습니다. 이 경우 모두 0 또는 1의 값을 취하는 3 개의 예상 검색어 (영어, 프랑스어, 아랍어)를 추가합니다.

어느 방법이든 여기 내 dplyr이 문제를 해결합니다. 는 CASE WHEN SQL 스타일 구문을 사용하며 읽기가 더 쉽습니다. 당신은 거의 거기 ifelse()에있어

require(tidyverse) 
dt.train2 <- dt.train2 %>% 
      mutate(language_string = case_when(language == "english" ~ 1, 
              language == "french" ~ 2, 
              language == "spanish" ~ 3, 
              TRUE ~ 0)) 
+0

맞아. 나는 이것에 정말로 새로운 것이다. 나는 당신의 해결책을 시도 할 것입니다. 고마워요! –

+0

@Gregor 잡기에 감사드립니다. 다른 경우에는 'TRUE ~ 0'의 catch-all로 편집했습니다. – Beau

2

, 당신은 단지 최종 else 결과 (와 닫는 괄호가없는 부부)가 필요합니다. 이 작업을 수행 할 수

dt.train2[, language_string := ifelse(
    language == "english", 1, 
    ifelse(language == "french", 2, 
     ifelse(language == "spanish", 3, 0) 
    ) 
) 
] 

몇 가지 다른 방법 :

는 조회 테이블을 확인하고 가입 :

# sample data 
dt = data.table(language = c("english", "french", "spanish", "arabic", "chinese", "pig latin")) 


lookup = data.table(language = c("english", "french", "spanish"), 
        language_string = c(1, 2, 3)) 

dt2 = merge(dt, lookup, by = "language", all.x = TRUE) 
dt2[is.na(language_string), language_string := 0] 

위의 조회 테이블 방법은 아마도 확장 성을 위해 가장 좋은 것입니다. 그러나, 인코딩 등의 소수를 들어, 당신은 또한 단지 그들 각각 설정할 수 있습니다 : 당신은 그냥 "스페인어"최종 다른 조건,`언어 ==를 놓치고

# start with the default, 0 
dt[, language_string := 0 ] 
# then do each of the exceptions 
dt[lanuage == "english", language_string := 1] 
dt[language == "french", language_string := 2] 
dt[language == "spanish", language_string := 3] 
+2

Fyi, 조회를위한 하나의 관용구는'dt [, v : = 0] [lookup, on =. (language), v : = language_string]'와 같아서 새로운 테이블을 만드는 대신 참조로 열을 추가합니다. – Frank

+0

완벽한, 그게 내가 찾고 있던거야! 대단히 감사합니다. –

0
language_options <- c("english", "french", "spanish", ...) 
dt.train2[, language_string := match(language, language_options)]