【问题标题】:function declaring column names声明列名的函数
【发布时间】:2021-08-11 10:20:40
【问题描述】:

我有一个用 R 编写的函数。基本上我是根据其值将函数应用于数据框列。谁能帮帮我?..................................

asd <- data.frame(a = c("High Impact", "High Impact", "Medium Impact"),
                  b = c("High Impact", "No Impact", "High Impact"),
                  c = c("Low Impact", "No Impact", "Medium Impact"))

final_score <- function(q1,q2,q3){
  # ifelse(c == "A", "Low", "High")
  if (q1 == "Not Applicable") {
    q1_value = 0
  } else if (q1 == "No Impact") {
    q1_value = 0
  } else if (q1 == "Low Impact") {
    q1_value = 1
  } else if (q1 == "Medium Impact") {
    q1_value = 2
  } else if (q1 == "High Impact") {
    q1_value = 3
  }
  
  if (q2 == "Not Applicable") {
    q2_value = 0
  } else if (q2 == "No Impact") {
    q2_value = 0
  } else if (q2 == "Low Impact") {
    q2_value = 1
  } else if (q2 == "Medium Impact") {
    q2_value = 2
  } else if (q2 == "High Impact") {
    q2_value = 3
  }
  
  if (q3 == "Not Applicable") {
    q3_value = 0
  } else if (q3 == "No Impact") {
    q3_value = 0
  } else if (q3 == "Low Impact") {
    q3_value = 1
  } else if (q3 == "Medium Impact") {
    q3_value = 2
  } else if (q3 == "High Impact") {
    q3_value = 3
  }
  fs  = q1_value + q2_value + q3_value
  return(fs)
}

###Expected output
asd$new <- final_score(asd$a,asd$b,asd$c)
              a           b             c       new
1   High Impact High Impact    Low Impact       7
2   High Impact   No Impact     No Impact       3
3 Medium Impact High Impact Medium Impact       7

我有一个用 R 编写的函数。基本上我是根据其值将函数应用于数据框列。谁能帮帮我?..................................

【问题讨论】:

    标签: r dataframe recode


    【解决方案1】:

    在dplyr 中,您可以使用case_when 和across -

    library(dplyr)
    
    asd %>%
      mutate(new = rowSums(across(.fns = ~case_when(. %in% c("Not Applicable", "No Impact") ~ 0, 
                                      . =="Low Impact" ~ 1, 
                                      . == "Medium Impact" ~ 2, 
                                      . == "High Impact" ~ 3))))
    
    #              a           b             c new
    #1   High Impact High Impact    Low Impact   7
    #2   High Impact   No Impact     No Impact   3
    #3 Medium Impact High Impact Medium Impact   7
    

    【讨论】:

    • 我写的完全一样(10分钟后)。很好的答案。
    • 嗨,假设还有一个名为 "d" 的列。在这种情况下,我们如何只取 3 列。 asd &lt;- data.frame(a = c("Low Impact", "High Impact", "Medium Impact"), b = c("High Impact", "No Impact", "High Impact"), c = c("Low Impact", "No Impact", "Medium Impact"), d = c(1,2,3))
    • 在across 你可以做across(a:c, ~case_when(.....))
    【解决方案2】:

    当您发现自己一遍又一遍地复制代码时,请考虑一下循环还是函数是更好的答案。这是一个在没有额外包的情况下进行计算的建议。但是,使用合适的包可以更简单地完成重新编码。 car 中的 recode 函数只是众多建议中的一个。

    # Your example data
    asd <- data.frame(a = c("High Impact", "High Impact", "Medium Impact"),
                      b = c("High Impact", "No Impact", "High Impact"),
                      c = c("Low Impact", "No Impact", "Medium Impact"))
    
    
    # a small function for one value:
    score <- function(value){
      if (value == "Not Applicable") return(0)
      if (value == "No Impact") return(0)
      if (value == "Low Impact") return(1)
      if (value == "Medium Impact") return(2)
      if (value == "High Impact") return(3)
      return(NA)
    }
    
    # apply that small function to each value in asd
    
    apply(asd, 1:2, score)
    
    # rowSums are the sums of the rows...
    
    asd$new <- rowSums(apply(asd, 1:2, score))
    
    print(asd)
    

    【讨论】:

      【解决方案3】:

      基本 R 选项

      asd$new <- rowSums(
        `dim<-`(
          as.integer(factor(
            as.matrix(asd),
            levels = c("Low Impact", "Medium Impact", "High Impact")
          )),
          dim(asd)
        ),
        na.rm = TRUE
      )
      

      给予

      > asd
                    a           b             c new
      1   High Impact High Impact    Low Impact   7
      2   High Impact   No Impact     No Impact   3
      3 Medium Impact High Impact Medium Impact   7
      

      【讨论】:

      • 如果不是两个字符串(“不适用”和“无影响”)共享相同的值 0,则转换为因子并使用数值将是一个不错的选择。
      • @crestor 是的,完全正确。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多