2017-05-09 72 views
0

首先,我知道關於在R中的if/else語句有很多問題,但沒有一個對我的具體情況有幫助,而且我一直在這一段時間裏掙扎着。鏈接如果 - 否與R中的多個do語句

我有一個數據幀,看起來像這樣:

metricx <- c(5, 4.8, 4.4, 3.6, 3.2, 2.1, 1.9, .5, .3, .1) 
df <- as.data.frame(metricx) 

我需要根據metricx(風險和答案)的值來創建兩個新的變量。

我知道這個工程....

df$risk <- ifelse(df$metricx >= 4.5, 'VERY HIGH', 'HIGH') 
df$risk <- ifelse(df$metricx < 3.5, 'MEDIUM', df$risk) 
df$risk <- ifelse(df$metricx < 2, 'LOW', df$risk) 

但顯然不是一個優雅的或有效的方式來做到這一點,因爲我會做幾次(我的數據集是非常大的,我有更多的組比這個)。我的理解是,R必須在每次調用ifelse時遍歷每條記錄,因此鏈接選項會更好。

我已經試過這...

ifelse(df$metricx >= 4.5, 
     (df$risk <- 'VERY HIGH' & 
     df$answer <- 'Y') 
     , 
ifelse(df$metricx >= 3.5, 
     (df$risk = 'HIGH' & 
     df$answer = 'Y') 
     , 
ifelse(df$metricx >= 2, 
     (df$risk = 'MEDIUM' & 
     df$answer = 'Y') 
     , 
ifelse(df$metricx >= .40, 
     (df$risk = 'LOW' & 
     df$answer = 'Y') 
     , 
(df$risk = 'LOW' & 
df$answer = 'N') 
)  
) 
) 
)  

我已經試過這...

if (df$metricx >= 4.5){ 
    df$risk = 'VERY HIGH' 
    df$answer = 'Y' 
} else if (df$metricx >= 3.5){ 
    df$risk = 'HIGH' 
    df$answer = 'Y' 
} else if (df$metricx >= 2){ 
    df$risk = 'MEDIUM' 
    df$answer = 'Y' 
} else if (df$metricx >= .40){ 
    df$risk = 'LOW' 
    df$answer = 'Y' 
} else { 
    df$risk = 'LOW' 
    df$answer = 'N' 
} 

,他們都給予不同的錯誤,這兩者都不我能理解。我有幾個不同的網站試圖解釋,但仍然無法弄清楚如何做到這一點。

我的問題: 1.爲什麼我的解決方案無法正常工作?他們似乎遵循我在R網站上看到的語法? 2.什麼是實現我想要的輸出的正確方法?

risk <- c('VERY HIGH', 'VERY HIGH', 'HIGH', 'HIGH', 'MEDIUM', 'MEDIUM', 'LOW', 'LOW', 'LOW', 'LOW') 
answer <- c('Y','Y','Y','Y','Y','Y','Y','Y','Y', 'N') 

want <- data.frame(metricx, risk, answer) 
+3

您應該使用'cut'來代替。 – lmo

+0

「ifelse」語句的集合並沒有真正的語法或用法。第二組將不起作用,因爲您正在使用無法在「if」中使用的矢量化條件。 – Gopala

+0

如果你發現一些非常複雜的東西,但實際上它是統計學中的一個常見操作,那麼爲此只存在一個簡單的R函數的可能性非常高。你只需要搜索它(考慮一下統計學家將命名操作來找到合適的搜索條件)。 – Roland

回答

2

我想用dplyr這就是你想要的,對吧?

library(dplyr) 
df <- df %>% mutate(risk = cut(metricx, c(0, 2, 3.5, 4.5, 6), 
        labels = c("LOW", "MEDIUM", "HIGH", "VERY HIGH"))) %>% 
    mutate(answer = ifelse(metricx < .4, "N", "Y")) 
+0

這是完美的。嵌套的if語句仍然困惑和沮喪,適用於所有其他語言,但這是一種高效優雅的解決方案。我從來沒有聽說過這個功能。謝謝。 – pyll

+0

你沒有得到嵌套的權利,它確實工作,在第三個位置,你開始新的'ifelse'而不是關閉它。或者查看'dplyr'中的'case_when'。 – Edwin

1

根據定義,您總能得到答案,這就是爲什麼我離開df $答案。嘗試:

metricx <- c(5, 4.8, 4.4, 3.6, 3.2, 2.1, 1.9, .5, .3, .1) 
df <- as.data.frame(metricx) 

myif<-function(x) { 
    if (x<2) y="LOW" else 
    if (x<3.5) y="MEDIUM" else 
     if (x<4.5) y="HIGH" else y="VERY HIGH" 
    return(y) 
} 
sapply(df$metricx,myif) 

# or: 

ifelse(df[1]<2,"LOW", 
     ifelse(df[1]<3.5,"MEDIUM", 
       ifelse(df[1]<4.5,"HIGH","VERY HIGH"))) 

# or (modified later): 

myif<-function(x) { 
    if (x<2) y="LOW" else 
    if (x<3.5) y="MEDIUM" else 
     if (x<4.5) y="HIGH" else y="VERY HIGH" 
     yv<-c(y,if (x<0.4) "N" else "Y") 
     return(yv) 
} 
sapply(df$metricx,myif) 
+0

實際上有條件下答案='N',所以這並不完全回答這個問題。我可以合併多個「做」行動,還是我需要單獨打電話? – pyll

+0

我真的會一次計算一個向量。正如我想到的那樣,上面的答案可能是最類似R的方式。 –

+0

是的,我同意切割是要走的路線 – pyll