2017-07-07 180 views
1

我想要使用sapply或lapply簡化以下多個ifelse代碼(仍然無法區分它們)。R sapply/lapply與多個ifelse語句

我的目標是根據如下所示的位置分配積分。

df$Point <- ifelse(df$Placement_v2 <= 1, 10, 
ifelse(df$Placement_v2 <= 10, 9, 
ifelse(df$Placement_v2 <= 25, 8, 
ifelse(df$Placement_v2 <= 50, 7, 1)))) 

此代碼的工作不錯,但我想打一個數據幀,只是我上面的代碼使用sapply或lapply(或任何其它功能)。

我試過這段代碼,但沒有按預期工作。只有放置1行得到10分和其他行結束了1

<第二碼>

df$Point <- sapply(df2$Placement, function(x) ifelse(df$Placement_v2 <= x, df2$Point[df2$Placement == x], 1)) 

我怎樣才能解決這個問題?

回答

0

您可以創建一個包含值和替換的數據框。然後你可以使用cut查找適當的值

dict = data.frame(replacement = c(10, 9, 8, 7, 1, 1), 
    values = c(0, 1, 10, 25, 50, 1e5)) 

#DATA 
set.seed(42) 
placement = sample(1:100, 15) 

cbind(placement, 
    new_placement = dict$replacement[as.integer(cut(placement, breaks = dict$values))]) 
#  placement new_placement 
# [1,]  92    1 
# [2,]  93    1 
# [3,]  29    7 
# [4,]  81    1 
# [5,]  62    1 
# [6,]  50    7 
# [7,]  70    1 
# [8,]  13    8 
# [9,]  61    1 
#[10,]  65    1 
#[11,]  42    7 
#[12,]  91    1 
#[13,]  83    1 
#[14,]  23    8 
#[15,]  40    7 
+0

感謝您的答覆。你的代碼很好地工作。我只是想了解更多關於剪切功能。我的水平顯示爲(1,10](10,25)(25,50)(50,100](100,200)(200,1e + 07)。是否有辦法使它像1](1,10]( 10,25](25,50](50,100)(100,200)(200?我試圖在我的數據框中不使用0或1e5。 – coldbeats

1

幾種方法去這個問題。我將使用data.table

library(data.table) 

set.seed(123) 
df <- data.table(Placement_v2 = runif(200, -10, 100)) 

第一種選擇,將評估出一個函數,然後lapply功能您Placement_v2列。這具有比你的嵌套ifelse陳述更清潔的好處。

funky <- function(x) { 

    if (x <= 1) { 
    val <- 10 
    } else if (x <= 10){ 
    val <- 9 
    } else if (x <= 25){ 
    val <- 8 
    } else if (x <= 50){ 
    val <- 7 
    } else { 
    val <- 1 
    } 

    return(val) 

} 

df[, Point := unlist(lapply(Placement_v2, funky))] 

結果:

 Placement_v2 Point 
    1: 21.633527  8 
    2: 76.713565  1 
    3: 34.987461  7 
    4: 87.131914  1 
    5: 93.451401  1 
---     
196: 41.318597  7 
197: 34.751585  7 
198: 62.515336  1 
199:  6.758128  9 
200: 53.015376  1 

我反而由子集劃分的數據,並通過每個子集分配接近這一點。您可以通過指定每個子集df[Placement_v2 <= 1],df[Placement_v2 >= 1 & Placement_v2 <= 10]等來完成此操作。但是,如果您按照正確的順序執行此操作,則可以避免雙重平等評估。

df[, Point := 1] 
df[Placement_v2 <= 50, Point := 7] 
df[Placement_v2 <= 25, Point := 8] 
df[Placement_v2 <= 10, Point := 9] 
df[Placement_v2 <= 1, Point := 10] 

可以得到相同的結果:

 Placement_v2 Point 
    1: 21.633527  8 
    2: 76.713565  1 
    3: 34.987461  7 
    4: 87.131914  1 
    5: 93.451401  1 
---     
196: 41.318597  7 
197: 34.751585  7 
198: 62.515336  1 
199:  6.758128  9 
200: 53.015376  1