【问题标题】:function does not proces input argument in R函数不处理 R 中的输入参数
【发布时间】:2020-08-22 19:29:44
【问题描述】:

我有一个包含 82 列的数据集。

我正在尝试编写一个函数,它将列名作为参数 (x),然后将该列中的名称转换为一个数字。每列唯一名称的数量不同。

样本数据:

df <- data.frame(column_1 = 1:10, column_2 = c("MT", "BM", "KA", "MT", "BM", "KA","MT", "BM", "KA", "MT"))

我预期的结果是这个函数将 column_2 转换为:

1,2,3,1,2,3,1,2,3,1

当我测试函数的主体时,它做了它应该做的事情: 1) 仅当它是字符且没有 NA 时才应用该功能 2)选择唯一值 3) 将该唯一值替换为从 1 到 n 的数字

UniekeNamen <- unique(VolledigeSet$MSZoning)
VervangenVoor <- c(1:length(VolledigeSet$MSZoning))
if (is.character(VolledigeSet$MSZoning) & sum(is.na(VolledigeSet$MSZoning) == 0)) {
  for (i in seq_along(UniekeNamen)) {
    VolledigeSet$MSZoning[VolledigeSet$MSZoning == UniekeNamen[i]] <- VervangenVoor[i]
  }
}

但是,当我将主体封装在函数中,并用列名替换参数 x 时,函数无法工作,就好像无法识别参数一样。没有错误消息,只是没有任何反应......

这是我写的函数:

name2num <- function(x) {
  UniekeNamen <- unique(x)
  VervangenVoor <- c(1:length(UniekeNamen))
  if (is.character(x) & sum(is.na(x) == 0)) {
   for (i in seq_along(UniekeNamen)) {
     x[x == UniekeNamen[i]] <- VervangenVoor[i]
   }
  }
}

你有什么建议改变这个函数吗?

提前致谢!

【问题讨论】:

  • 主要问题是函数没有return 值...正在寻找答案。
  • 提示:如果您将column_2 转换为factor (df$column_2 &lt;- as.factor(df$column_2),您将能够使用levels(df$column_2) &lt;- 1:length(levels(df$column_2)) 获得结果。

标签: r function arguments


【解决方案1】:

您的主要问题是您的函数需要return 完整修改后的x。您可以通过将xreturn(x) 作为函数的最后一行来做到这一点。

当我修复返回问题并在您的示例数据上运行函数时,df$column_2 未修改,因为该列是一个因素,而不是一个字符(因为我还没有升级到 R 4.0),所以我演示了它是强制的column_2 到字符。

这会给我们这个函数:

name2num <- function(x) {
  UniekeNamen <- unique(x)
  VervangenVoor <- c(1:length(UniekeNamen))
  if (is.character(x) & sum(is.na(x) == 0)) {
   for (i in seq_along(UniekeNamen)) {
     x[x == UniekeNamen[i]] <- VervangenVoor[i]
   }
  }
  x
}

name2num(as.character(df$column_2))
# [1] "1" "2" "3" "1" "2" "3" "1" "2" "3" "1"

请注意,由于列的元素一次更改一个,因此列的类保持不变。如果你希望输出是数字而不是字符,你应该让函数返回as.numeric(x)

我们可以通过 R 的 factor 类来改进功能,它已经做得很好了。这将被矢量化并且更有效。它还将让函数在 factor 列上工作,因为转换是一次性的,而不是一次一个元素。

name2num_gt = function(x) {
  if ((is.character(x) | is.factor(x)) & sum(is.na(x) == 0)) {
    x = as.integer(factor(x, levels = unique(x)))
  }
  x
}
name2num_gt(as.character(df$column_2))
# [1] 1 2 3 1 2 3 1 2 3 1

有很多方法可以将此应用于数据中的所有列。一种选择是df[] = lapply(df, name2num_gt)

【讨论】:

    【解决方案2】:

    您必须返回输出的向量,该向量又需要通过替换应用于现有数据集。

    name2num <- function(x) {
      UniekeNamen <- unique(x)
      VervangenVoor <- c(1:length(UniekeNamen))
      if (is.character(x) !=0 & sum(is.na(x) == 0)) {
        for (i in seq_along(UniekeNamen)) {
          x[x == UniekeNamen[i]] <- VervangenVoor[i]
        }
        return(as.factor(x))
      }
    }
    
    
    df$column_2 <- name2num(df$column_2)
    df 
    

    输出:

       column_1 column_2
    1         1        1
    2         2        2
    3         3        3
    4         4        1
    5         5        2
    6         6        3
    7         7        1
    8         8        2
    9         9        3
    10       10        1
    

    P.S.:如果您想将 column_2 设为数字,请改用 return(as.numeric(x))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-14
      相关资源
      最近更新 更多