【问题标题】:R if returns list in data frame column need simple characterR如果数据框列中的返回列表需要简单字符
【发布时间】:2020-03-09 23:39:07
【问题描述】:

问题上下文:返回的列表需要 chr(字符)。创建函数 fun_grade() 以有条件地选择数值(作为字符)返回并在数据框内更新。在数据框 df_credit_status$grade 字段中返回了一个列表。也许我需要转换为 as.character,或者有更好的函数方法来更改字符列?

list returned need simple chr

fun_grade <- function(grade) {
  if (grade == "A") return("100")
  if (grade == "B") return("80")
  if (grade == "C") return("60")
  if (grade == "D") return("40")
  if (grade == "D") return("20")
  if (grade == "F") return("10")
  return
}
df_credit_status$grade <- sapply(df_credit_status$grade, FUN=fun_grade)

【问题讨论】:

    标签: r function if-statement switch-statement


    【解决方案1】:

    不要使用多个if 条件,而是使用命名向量来替换值。

    setNames(c(100, 80, 60, 40, 20, 10),
                  LETTERS[1:6])[as.character(df_credit_status$grade)]
    

    使用一个可重现的小例子

    set.seed(24)
    v1 <- sample(LETTERS[1:6], 25, replace = TRUE)
    setNames(c(100, 80, 60, 40, 20, 10), LETTERS[1:6])[v1]
    #   C   B   C   E   B   F   B   A   D   A   A   E   E   A   E   E   D   E   B   A   D   C   E   B   A 
    #  60  80  60  20  80  10  80 100  40 100 100  20  20 100  20  20  40  20  80 100  40  60  20  80 100 
    

    另外,if/else 没有矢量化,因此需要 ifelse/if_else/case_when (反正效率不会那么高)

    【讨论】:

    • 非常感谢,以前从未使用过 setName(),不错的简洁小代码解决方案
    【解决方案2】:

    好的,我模拟了一个数据框:

    df_credit_status <- data.frame(
      grade = sample(
        c("A", "B", "C", "D", "E", "F"), 
        size = 200, 
        replace = TRUE)
    )
    

    并修改了您的代码:

    fun_grade <- function(grade) {as
      if (grade == "A") { 
        return("100")
      } else if (grade == "B") {
        return("80")
      } else if (grade == "C") {
        return("60")
      } else if (grade == "D") {
        return("40")
      } else if (grade == "E") {
        return("20")
      } else if (grade == "F") {
        return("10")
      }
    }
    
    df_credit_status$equiv_grade <- sapply(df_credit_status$grade, 
                                           FUN = fun_grade)
    

    得到:

    > head(df_credit_status)
      grade equiv_grade
    1     F          10
    2     D          40
    3     F          10
    4     F          10
    5     C          60
    6     C          60
    

    就我个人而言,我会使用tidyverse 库:

    library(tidyverse)
    
    df_credit_status <- data.frame(
      grade = sample(
        c("A", "B", "C", "D", "E", "F"), 
        size = 200, 
        replace = TRUE)
    )
    
    
    df_credit_status <- df_credit_status %>% 
      mutate(
        equiv_grade = case_when(
          grade == "A" ~ "100",
          grade == "B" ~ "80",
          grade == "C" ~ "60",
          grade == "D" ~ "40",
          grade == "E" ~ "20",
          grade == "F" ~ "10"
        )
      )
    # change the equivalencies above to numbers if you need that
    

    我正在使用第二列,因此原始信息不会丢失。

    HTH

    【讨论】:

    • 嘿,非常感谢...我的 wifi 这么晚才恢复,现在一切正常,感谢您的宝贵帮助
    猜你喜欢
    • 2021-05-07
    • 2020-10-05
    • 1970-01-01
    • 2023-04-09
    • 2021-11-24
    • 1970-01-01
    • 2021-12-21
    • 2017-08-01
    • 2019-08-04
    相关资源
    最近更新 更多