2017-07-07 185 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