【问题标题】:R: Functionization of a piece of code gives different results [closed]R:一段代码的功能化会产生不同的结果[关闭]
【发布时间】:2022-01-22 23:57:52
【问题描述】:

我已经编写了一段代码来重新编码我拥有的一些变量。它看起来像这样:

这是我的示例 df:

mydf <- structure(list(SubjectId = 1:10, EventName = structure(c("Visit 11", 
"Visit 7", "Visit 15", "Visit 11", "Visit 7", "Visit 11", "Visit 15", 
"Visit 11", "Visit 7", "Visit 7"), label = "Event name", format.sas = "$"), 
    P1A1_BS1ORRES = structure(c(1, 1, 2, 1, 2, 1, 2, 1, 1, 1), label = "Path1: Result", format.sas = "BSRESA")), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

这就是我所做的:

codeList <- list("1" = "AAA",
                 "2" = "BBB",
                 "3" = "CCC",
                 "4" = "DDD",
                 "5" = "EEE")

col <- 'P1A1_BS1ORRES'
list <- codeList
df <- mydf
df[[col]] <- as.character(df[[col]])

for (k in 1:length(list)){
  df[df[[col]] ==  names(list)[k], col] <- list[[k]]
}

这会将P1A1_BS1ORRES 列中的数字键正确转换为它们各自的标签。但是,当我把它放在一个函数中时,我无法让它工作......这是我所做的:

recodeCol <- function(df, col, list){
  
  df[[col]] <- as.character(df[[col]])
  
  for (k in 1:length(list)){
    df[df[[col]] ==  names(list)[k], col] <- list[[k]]
  }
  
}
recodeCol(mydf, 'P1A1_BS1ORRES', codeList)

它返回NULL 有谁知道为什么当我把它变成一个函数时这不起作用?

【问题讨论】:

  • 你没有从你的函数中返回任何东西——把df放在函数的最后一行,它应该可以工作吗?我还建议不要使用名为 list 的参数,因为这与内置函数 list() 冲突
  • 天啊,我觉得自己好蠢。感谢您的帮助和提示!

标签: r function


【解决方案1】:

更简单的解决方案

recodeCol <- function(df, col, recoder_vec) {
  df[[col]] <- recoder_vec[df[[col]]]
  df
}

你使用它:

recodeCol(mydf, col, c("AAA", "BBB", "CCC", "DDD", "EEE"))

说明

正如@CalumYou 评论的那样,您的问题是for 循环返回NULL - 所以netire 函数返回NULL。诀窍是在最后重新调用df,因为在 R 中,最后一个表达式的值会自动返回 - 就像在任何其他函数式编程语言(R 是)中一样。

在您的代码中,您有列表

codeList <- list("1" = "AAA",
                 "2" = "BBB",
                 "3" = "CCC",
                 "4" = "DDD",
                 "5" = "EEE")

这可能是一个向量,因为所有元素都是同一类型,并且每个实例的数量不一样。

因为在:

  for (k in 1:length(list)){
    df[df[[col]] ==  names(list)[k], col] <- list[[k]]
  }

您查找出现在df[[col]] 中的codeList 的名称,以将它们替换为codeList 的值。

您必须这样做,因为您的codeList 是一个列表。 但是如果你把codeList做成一个向量,你可以使用向量化。

此外,您还可以:

df[[col]] <- as.character(df[[col]])

确保所有名称都是字符,因为您在 codeList 中设置了所有名称字符。

但是codeList 中的名称,如果您使用向量,则只是向量的索引。如何使用这个事实? 它将给出给定的新解决方案,其中数字df[[col]] 值用作recoder_vec 中的查找索引。如果不确定它们是数字,您可以通过替换 recoder_vec[as.numeric(df[[col]])] 来确保它们是数字。

如果df[[col]] 是因子类型,并且有时因子的顺序与假设不同,则这样做更安全: recoder_vec[as.numeric(as.character(df[[col]]))].

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多