【问题标题】:How to recode many data frame columns with same function如何重新编码具有相同功能的许多数据框列
【发布时间】:2017-08-16 19:25:44
【问题描述】:

我有一个这样的数据框:

CriterionVar Var1 Var2 Var3
3            0    0    0
1            0    0    0
2            0    0    0
5            0    0    0 

我想根据CriterionVar 的值重新编码Var1Var2Var3 的值。在伪代码中,它会是这样的:

for each row
   if (CriterionVar.value >= Var1.index) Var1 = 1
   if (CriterionVar.value >= Var2.index) Var2 = 1
   if (CriterionVar.value >= Var3.index) Var3 = 1

重新编码的数据框如下所示:

CriterionVar Var1 Var2 Var3
3            1    1    1
1            1    0    0
2            1    1    0
5            1    1    1

显然,这不是完成它的方法,因为 (1) VarN 列的数量由数据值决定,并且 (2) 它很丑。

感谢任何帮助。

【问题讨论】:

  • 是的。编辑。谢谢。

标签: r dataframe recode


【解决方案1】:

对于更一般的 CriterionVar 值,您可以使用 outer 构造一个逻辑矩阵,您可以将其用于索引,如下所示:

dat[2:4][outer(dat$CriterionVar, seq_along(names(dat)[-1]), ">=")] <- 1

在本例中,返回

dat
  CriterionVar Var1 Var2 Var3
1            3    1    1    1
2            1    1    0    0
3            2    1    1    0
4            5    1    1    1

第二种方法使用col,返回列索引的矩阵,更直接一点:

dat[2:4][dat$CriterionVar >= col(dat[-1])] <- 1

并返回所需的结果。


数据

dat <-
structure(list(CriterionVar = c(3L, 1L, 2L, 5L), Var1 = c(0L, 
0L, 0L, 0L), Var2 = c(0L, 0L, 0L, 0L), Var3 = c(0L, 0L, 0L, 0L
)), .Names = c("CriterionVar", "Var1", "Var2", "Var3"), class = "data.frame",
row.names = c(NA, -4L))

【讨论】:

    【解决方案2】:
    df[,-1] = lapply(2:NCOL(df), function(i) as.numeric(df[,1] >= (i-1)))
    df
    #  CriterionVar Var1 Var2 Var3
    #1            3    1    1    1
    #2            1    1    0    0
    #3            2    1    1    0
    #4            5    1    1    1
    

    数据

    df = structure(list(CriterionVar = c(3L, 1L, 2L, 5L), Var1 = c(1, 
    1, 1, 1), Var2 = c(1, 0, 1, 1), Var3 = c(1, 0, 0, 1)), .Names = c("CriterionVar", 
    "Var1", "Var2", "Var3"), row.names = c(NA, -4L), class = "data.frame")
    

    【讨论】:

    • 我想知道这里是否可以使用df[-1] &lt;- lapply(df[-1], function(i)...) idiom 来简单地更新现有的df,从而避免整个setNames
    【解决方案3】:

    我是vapply 的忠实拥护者:它很快,而且你知道它会返回什么形状。唯一的问题是生成的矩阵通常是您想要的“横向”版本。但是t() 很容易解决这个问题。

    n_var_cols <- 3
    truncated_criterion <- pmin(dat[["CriterionVar"]], n_var_cols)
    row_template <- rep_len(0, n_var_cols)
    
    replace_up_to_index <- function(index) {
      replace(row_template, seq_len(index), 1)
    }
    
    over_matrix <- vapply(
      X         = truncated_criterion,
      FUN       = replace_up_to_index,
      FUN.VALUE = row_template
    )
    over_matrix <- t(over_matrix)
    
    dat[, -1] <- over_matrix
    dat
    #   CriterionVar Var1 Var2 Var3
    # 1            3    1    1    1
    # 2            1    1    0    0
    # 3            2    1    1    0
    # 4            5    1    1    1
    

    前三行有一些记账,但没有什么太糟糕的。我使用pmin() 将条件值限制为不大于VarN 列的数量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      • 1970-01-01
      • 2018-08-18
      • 2020-01-26
      相关资源
      最近更新 更多