0

我正在编写我的第一个函数(包括任何其他编程语言),我对if,elseifelse. 我搜索了很多例子,但没有一个对我来说很清楚。

情况 - 我正在尝试根据客户成为客户的时间来衡量客户,然后将其转化为一个因素。

#Sample Data
clientID <- round(runif(2,min=2000, max=3000),0)
MonthsSinceSignUp <- round(runif(20,min=1, max=60),0)
df <- data.frame(cbind(clientID,MonthsSinceSignUp))

对于给定的客户,我想确定他们是否已经这样做了不到一年,超过一年,但不到 2 年,等等。

这是我第一次破解函数:

ClientAgeRange <- function(MonthsSinceSignUp) {
  if (MonthsSinceSignUp < 13) {ClientAgeRange <- '1 year'}
} else {
  if (MonthsSinceSignUp > 13 & MonthsSinceSignUps < 25) {ClientAgeRange <- '2 years'}
} else {ClientAgeRage <- '3+ years'}

我不断收到的错误是: Error: unexpected '}' in "}",这表明我缺少或有一个额外的右括号。但是,尽管我遇到了麻烦,但我找不到它。但是 - 我认为总的来说,我没有将正确的结构应用于函数。我正在尝试制作一个if this, then set this variable as that. 如何正确构建此功能?

最后 - 如果我想将函数的输出添加到dataframe,这样做是apply正确的方法吗?

4

3 回答 3

5

分两部分回答:

  1. 一个提示
  2. 一个修复

小费:

我的第一个提示是使用进行括号匹配的代码编辑器。例如,在Notepad++你得到这个:

PS。我不推荐Notepad++- 改用 Rstudio - 我只是Notepad++因为花哨(因此很容易发现)颜色而使用

在此处输入图像描述

请注意,突出显示的大括号(红色)与函数中间的大括号匹配。这表明您的 first 末尾有多余的大括号if。所以,先解决这个问题:

在此处输入图像描述

好的,现在没有匹配的大括号(没有突出显示的红色),因此您需要在函数末尾添加缺少的大括号:

在此处输入图像描述


修复:

但是,如果您使用cut,您可以大大简化您的功能,它旨在进行这种类型的分析:

ClientAgeRange <- function(x) {
  cut(x, breaks=c(0, 13, 25, Inf), labels=c("1 year", "2 years", "3+ years"))
}

试试你的代码:

ClientAgeRange(df$MonthsSinceSignUp)
 [1] 2 years  1 year   3+ years 2 years  3+ years 3+ years 2 years  2 years  3+ years 3+ years 1 year  
[12] 3+ years 2 years  3+ years 3+ years 3+ years 3+ years 3+ years 3+ years 3+ years
Levels: 1 year 2 years 3+ years
于 2012-07-30T16:25:29.110 回答
2
if (MonthsSinceSignUp < 13) {ClientAgeRange <- '1 year'}
}

你有一个额外的 } 这里。

作为一般规则,采用约定来格式化代码是一个好主意。我强烈推荐的一个约定是始终将“块”的主体(这里我使用块作为“{} 内的东西”的通用术语,包括函数主体、if 语句和循环)放在自己的行上, 如下:

ClientAgeRange <- function(MonthsSinceSignUp) {
  if (MonthsSinceSignUp < 13) {
    ClientAgeRange <- '1 year'
  } else if (MonthsSinceSignUp > 13 & MonthsSinceSignUps < 25) {
    ClientAgeRange <- '2 years'
  } else {
    ClientAgeRage <- '3+ years'
  }
}

看看这如何让一切变得更清晰?


至于你的第二个问题,一个没有副作用的函数接受输入、执行操作并返回输出。您现在没有任何返回值,从您的命名约定来看,您似乎有点困惑。

试试这个:

ClientAgeRange <- function(MonthsSinceSignUp) {
  if (MonthsSinceSignUp < 13) {
    result <- '1 year'
  } else if (MonthsSinceSignUp > 13 & MonthsSinceSignUps < 25) {
    result <- '2 years'
  } else {
    result <- '3+ years'
  }
  return(result)
}

在 R中return(是可选的,但它会帮助你更清楚地思考函数。

于 2012-07-30T16:15:24.547 回答
2

尝试以下操作(请注意,我曾经else if使它更简单):

ClientAgeRange <- function(MonthsSinceSignUp) {
  if (MonthsSinceSignUp < 13) {
      ClientAgeRange <- '1 year'
  } else if (MonthsSinceSignUp > 13 & MonthsSinceSignUp < 25) {
      ClientAgeRange <- '2 years'
  } else {ClientAgeRage <- '3+ years'}
} 

然后,您可以将其添加到您的数据框中,如下所示:

df$ClientAgeRange <- sapply(MonthsSinceSignUp, ClientAgeRange)

正如您所说, apply (我在这种情况下使用了 sapply ;例如,您可以在几个地方阅读有关不同应用功能的信息)是正确的方法。这是因为我们不能简单地将整个向量传递给函数;它需要单个元素进行必要的比较。

于 2012-07-30T16:16:24.553 回答