使用函数转换数据框中的数值变量

时间:2016-04-28 06:13:19

标签: r

背景

这是尝试改进以前的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"))

问题

  • 我对该代码的错误是什么?我设法使可选参数工作,但代码中有一些错误。当我测试它时,列表中的变量将转换为零。

警示性建议

  • 如果你对这个问题进行投票,至少可以说明原因!

2 个答案:

答案 0 :(得分: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
}

没有listofvars

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

加上listofvars

 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)

答案 1 :(得分:0)

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

################################################################################
#
# 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)
}