【问题标题】:Transforming numerical variables in a dataframe with a function使用函数转换数据框中的数值变量
【发布时间】:2016-04-28 06:13:19
【问题描述】:

背景

这是改进以前的question 的尝试。这个想法是创建一个函数,在其中我传递一个数据框和一个可选的带有变量名称的向量,然后该函数迭代数据框中的变量,如果它们是数字的,它们将被转换。如果还传递了名称向量,则仅迭代列表中的那些。

使用的工具

  • 为了创建一个“可选”参数,我使用了 missing() 函数。 Source.

  • 迭代向量的语法灵感来自这个讨论here

代码和我卡住的地方:

transformDivideThousand <- function(data_frame, listofvars){
    if (missing(listofvars)) {
        data_frame[, sapply(data_frame, is.numeric)] =
        data_frame[, sapply(data_frame, is.numeric)]/1000
    } else {
        for (i in names(data_frame)) {
            for (i in listofvars) {
                data_frame[[i]]<-data_frame[[i]]/1000
            }
        }
    }
    return(data_frame)
}

调用看起来像:

test <- transformDivideThousand(cases, c("col2", "col3", "col15"))

问题

  • 我在该代码上遇到了什么问题?我设法使可选参数起作用,但代码中有问题。当我对其进行测试时,列表中的变量将转换为零。

警示性建议

  • 如果您对这个问题投反对票,至少要说明原因!

【问题讨论】:

  • 也许if (i %in% listofvariables) { ?请参阅set 了解更多信息。

标签: r


【解决方案1】:

你可以这样做:

# data
 head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

功能

foo_divide <- function(x, y){
  foo <- function(x) if(is.numeric(x)) x/1000 else x # function to divide numeric columns by 1000
  if(missing(y)) y <- 1:ncol(x) # set y if missing
  x[, y] <-  lapply(x[, y], foo)
  as.data.frame(x) # return
}

没有变量列表

head(foo_divide(iris))
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1       0.0051      0.0035       0.0014       2e-04  setosa
2       0.0049      0.0030       0.0014       2e-04  setosa
3       0.0047      0.0032       0.0013       2e-04  setosa
4       0.0046      0.0031       0.0015       2e-04  setosa
5       0.0050      0.0036       0.0014       2e-04  setosa
6       0.0054      0.0039       0.0017       4e-04  setosa

加上变量列表

 head(foo_divide(iris, c("Petal.Length", "Petal.Width", "Species")))
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5       0.0014       2e-04  setosa
2          4.9         3.0       0.0014       2e-04  setosa
3          4.7         3.2       0.0013       2e-04  setosa
4          4.6         3.1       0.0015       2e-04  setosa
5          5.0         3.6       0.0014       2e-04  setosa
6          5.4         3.9       0.0017       4e-04  setosa

您也可以使用数值向量来指定列

foo_divide(iris, 1:3)

【讨论】:

    【解决方案2】:

    在 cmets 的帮助下,这是一个解决方案:

    ################################################################################
    #
    # transformDivideThousand(dataframe, optional = vectorListOfVariables)
    #
    # Definition: This function applies a transformation, dividing variables by
    # 1000. If the vector is passed it applies the transformation to all variables
    # in the dataframe.
    #
    # Example: df <- transformDivideThousand (cases, c("label1","label2"))
    #
    ################################################################################
    transformDivideThousand <- function(data_frame, listofvars){
        if (missing(listofvars)) {
            data_frame[, sapply(data_frame, is.numeric)] =
            data_frame[, sapply(data_frame, is.numeric)]/1000
        } else {
            for (i in names(data_frame)) {
                if (i %in% listofvars) {
                    data_frame[,i] = data_frame[,i]/1000
                }
            }
        }
        return(data_frame)
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-21
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 2022-11-16
      • 1970-01-01
      • 2020-07-27
      • 1970-01-01
      相关资源
      最近更新 更多