R 使用 case_when 对数值进行分类

R categorize numeric value using case_when

我有一个数据,其中变量 id 作为唯一原点,变量 distance_km 告诉我们到最近的兴趣点的距离。我需要一种更好的方法将每个 id 分类为距离兴趣点 x 公里以内。我可以使用 case_when 手动执行此操作,但我想知道是否有更好的方法可以在开始时简单地初始化所需的值。

最后一个with_x_km必须是10的倍数。所以在我的测试例子中,这是50。

# sample data
data <- tribble(
  ~id, ~distance_km,
  "1",   0.5, 
  "2",   1.5, 
  "3",   10.5, 
  "4", 43, 
  "5", 20.7
  
)

max(data$distance_km)

# so the max value should round up to 50
# if this was 51, we would choose 60

# manually using case_when

final <- data %>% 
  mutate(within_x_km = 
           case_when(distance_km < 1 ~ "1 km",
                     distance_km < 10 ~ "10 km",
                     distance_km < 20 ~ "20 km",
                     # max value we determined earlier
                     distance_km < 50 ~ "50 km",
                     TRUE ~ "NA"))

我正在寻找一种更有效的方法来做到这一点。例如,也许有一种方法可以预先创建分箱并自动对数值变量进行分类。类似于以下内容:

# the last value should always round up to a multiple of 10
within_km <- c(1, 10, 20, 50)

谢谢

我们可以使用cut函数:

library(dplyr)

labels <- c("1 km", "10 km", "20 km", "50 km")

data %>% 
  mutate(within_km =  cut(distance_km, 
                          breaks = c(0, 1, 10, 20, 50), 
                          labels = labels))
  id    distance_km within_km
  <chr>       <dbl> <fct>    
1 1             0.5 1 km     
2 2             1.5 10 km    
3 3            10.5 20 km    
4 4            43   50 km    
5 5            20.7 50 km 

另一种可能性,它捕获 vec 中最接近的较高值。

vec <- c(1, 10, 20, 50)
sapply(data$distance_km, \(x) paste(vec[which(vec - x == min((vec - x)[(vec- x) > 0]))], "km"))
# [1] "1 km"  "10 km" "20 km" "50 km" "50 km"