将dataframe列映射到动态值范围

时间:2018-04-19 16:17:24

标签: r

我有一系列我希望将类映射到的值。

例如,如果我的范围是

  c(1000,2000,3000)

我的数据框是:

  x
  1
  5000 
  600
  1500

然后,我想创建第二列,根据以下规则映射列'x':

1)如果x大于范围内的所有值,则映射到范围中的最大值

2)否则映射到范围内的最接近的值

对于这个例子,它看起来像:

 x     map
 1     1000
 5000  3000
 600   1000
 1500  2000

如果我知道长度是固定的,我可以使用if语句。但由于长度不固定,我该如何做呢?

4 个答案:

答案 0 :(得分:1)

只需编写一个满足您需求的函数,并sapply将其编写为df$x,这将把书面函数应用于df$x中的每个元素。

df <- data.frame(x = c(1,5000,600,1500))

mapping_fun <- function(x) {
    # Set your vector here
    vec <- c(1000,2000,3000)
    # Determine the range of your given vector
    vec_range <- range(vec)
    # Return a value with your rules below
    if (x > vec_range[2]) {
        return(vec_range[2])
    }
    else {
        return(min(vec[vec > x]))
    }
}

df$mapping <- sapply(df$x, mapping_fun)

答案 1 :(得分:1)

cut用于分箱数据。我们可以将max设置为范围的最大值,但是将min设置为-Inf,然后将post-hoc设置为最大值。

r = c(1:3 * 1000)
x = c(1, 5000, 600, 1500)

result = as.numeric(as.character(cut(x, breaks = c(-Inf, r), labels = r)))
result[is.na(result)] = max(r)
result
# [1] 1000 3000 1000 2000

答案 2 :(得分:1)

以下是使用findInterval

的选项
df1$map1 <- pmin(v1[findInterval(df1$x, v1) + 1], max(v1), na.rm = TRUE)
df1$map1
#[1] 1000 3000 1000 2000

数据

v1 <- c(1000,2000,3000)
df1 <- structure(list(x = c(1L, 5000L, 600L, 1500L)), .Names = "x", 
 class = "data.frame", row.names = c(NA, -4L))

答案 3 :(得分:0)

试试这个

list <- c(1000,2000,3000)

df <- data.frame(x = c(1, 5000, 600, 1500))

minx <- function(x){
  val <- list[list > x]
  if(length(val) == 0) {
    return(max(list))
  } else{
    return(min(val))
  }
}

df$x2 <- apply(df['x'], 1, function(x) minx(x))

df
# x   x2
# 1    1 1000
# 2 5000 3000
# 3  600 1000
# 4 1500 2000