r语言 - 调整函数的输入,从字符串到数据帧



我的数据上有一列ISBN(没有NA(,每列都填充了一个长度为10的字符串。我像这样检查我的列的结构,我得到:

str(ISBN) 
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   20824 obs. of  1 variable:
$ ISBN: chr  "1319078575" "1319078575" "1319080790" "1319080790" ...

现在,我创建了一个函数,该函数将长度为 10 的字符串(ISBN(作为输入,并检查它是否有效并输出 TRUE 或 FALSE。根据我的测试工作正常(我认为(。

ValidateISBN <-  function(x){
  isbnum <- unlist(strsplit(x,split = NULL))
  if(tail(isbnum, n = 1) == "X"){
    isbnum[10] <- 10
  }
  x <- as.numeric(isbnum)
  y <- c(10,9,8,7,6,5,4,3,2,1)
  innerprod <- sum(x*t(y))
  if(innerprod %% 11 == 0){
    x = TRUE
  }
  else{
    x = FALSE
  }
  return(x)
}

我尝试了这些检查:

#Testing my function:
a <- "131908057X"
b <- "1319080529"
c <- "1319078575"
ValidateISBN(a)
ValidateISBN(b)
ValidateISBN(c)

他们工作了。所以我的下一个(天真的(步骤是尝试将我的 ISBN 列传递给我的函数,并希望作为与 TRUE 和 FALSE 的 ISBN 序列长度相同的类似列的输出。但它没有用。为了能够传递整个列,我应该对函数进行哪些调整?谢谢。

如果这不是我能做的事情(请原谅我的无知,我是初学者(,我可以更改/暂时更改我的 df 列,以便我可以将其元素(行(传递到函数中吗?

您也可以使用 sapply 简单地逐个元素应用函数。下面给出了一个工作示例,为了说明目的,我还添加了一个无效的 ISBN:

# sample data
a <- "131908057X"
b <- "1319080529"
c <- "1319078575"
d <- "9999999990"
df = data.frame(ISBN=c(a,b,c,d),stringsAsFactors = F)
df$valid = sapply(df$ISBN, ValidateISBN)

返回:

        ISBN valid
1 131908057X  TRUE
2 1319080529  TRUE
3 1319078575  TRUE
4 9999999990 FALSE

希望这有帮助!


或者,但在我看来不太好,您可以将函数重写为

ValidateISBN <-  function(X){
  result = rep(FALSE, length(X))
  for(i in 1:length(X))
  {
    x = X[i]
    isbnum <- unlist(strsplit(x,split = NULL))
    if(tail(isbnum, n = 1) == "X"){
      isbnum[10] <- 10
    }
    x <- as.numeric(isbnum)
    y <- c(10,9,8,7,6,5,4,3,2,1)
    innerprod <- sum(x*t(y))
    if(innerprod %% 11 == 0){
      x = TRUE
    }
    else{
      x = FALSE
    }
    result[i] = x
  }
  return(result)
}

在这种情况下,您可以将其称为

ValidateISBN(df$ISBN)

但不会有真正的速度差异。为此,您还必须对函数的内部进行矢量化。

最新更新