清理R中的列数据

时间:2014-11-04 20:02:54

标签: r

您好我写了这个函数来清理R中的数据:

periodCleanse <- function(x) {
    if (x == ""){
        return ("");
    }
    else if (substr(x, nchar(x), nchar(x)) == "M"){
        return(30*as.numeric(substr(x, 1, nchar(x)-1)));
    }
    else if (substr(x, nchar(x), nchar(x)) == "Y"){
        return(365*as.numeric(substr(x, 1, nchar(x)-1)));
    }
    else if (substr(x, nchar(x), nchar(x)) == "D"){
        return (as.numeric(substr(x, 1, nchar(x)-1)));
    }
}

我的df看起来像这样:

period
3M
5Y

1D
7M

我想打电话

df$period <- periodCleanse(df$period))

但我得到了:

Warning message:
In if (x == "") { :
  the condition has length > 1 and only the first element will be used

没有任何反应。我该怎么办?

2 个答案:

答案 0 :(得分:0)

您的函数接受向量(数据框的列),但只返回一个值。你可以通过apply将函数传递给向量的每个元素:sapply(df$period, periodCleanse)。请注意,nchar仅在您的列是字符向量而非因子时才有效。

触发警告是因为你正在使用一个布尔值(来自x == "")并在if条件下使用它; R将仅使用第一个元素,并生成警告,因为它可能不是您想要的。作为替代方案,您可以将多个ifelse调用链接起来进行矢量化,但是对于多个条件,这可能会变得难以处理。

答案 1 :(得分:0)

我只想创建一个矢量化函数,既可以避免编写无尽的if else并在循环中运行它(sapply

periodCleanse2 <- function(x){
  matchDat <- data.frame(A = c("M", "Y", "D"), B = c(30, 365, 1)) # You can take that part out of the function for improving speed
  indx <- gsub("\\d", "", x)
  indx2 <- as.numeric(gsub("[A-Z]", "", x))
  matchDat$B[match(indx, matchDat$A)] * indx2
}

periodCleanse2(df$period)
## [1]   90 1825   NA    1  210