替代多个条件的嵌套ifelse语句的长列表

时间:2016-07-09 11:55:46

标签: r if-statement

我有以下数据框

    structure(list(FY = c("2015-2016", "2015-2016", "2015-2016", 
"2015-2016"), YEARMN = structure(c(2015.25, 2015.25, 2015.25, 
2015.25), class = "yearmon"), BRAND = c("3M CAR CARE", "CAR CARE 3M", 
"CAR CARE 3M", "CAR CARE 3M"), variable = structure(c(1L, 
2L, 3L, 4L), .Label = c("IstWEEKRent", "IIndWEEKRent", "IIIrdWEEKRent", 
"IVthWEEKRent", "mymonth"), class = "factor"), value = c("0", 
"17500", "85000", "212500"), mymonth = c("Apr", "Apr", "Apr", 
"Apr")), .Names = c("FY", "YEARMN", "BRAND", "variable", "value", 
"mymonth"), row.names = c(NA, 4L), class = "data.frame")

实际数据框如下所示:

         FY   YEARMN       BRAND      variable  value mymonth
1 2015-2016 Apr 2015 3M CAR CARE   IstWEEKRent      0     Apr
2 2015-2016 Apr 2015 CAR CARE 3M  IIndWEEKRent  17500     Apr
3 2015-2016 Apr 2015 CAR CARE 3M IIIrdWEEKRent  85000     Apr
4 2015-2016 Apr 2015 CAR CARE 3M  IVthWEEKRent 212500     Apr

我的月份列从4月到3月有几个月......每个月在我的数据集中有4周,在列变量中给出。我试图创建一个4月至3月的周数,从1到48开始。我想给出符合条件的第1周

variable == "IstWeekRent" & mymonth == "Apr"

我使用了ifelse函数来完成这个......这很好......但是当我将它包含在我闪亮的应用程序中时,我收到以下错误:

Error in parse(file, keep.source = FALSE, srcfile = src, encoding = enc) : 
  contextstack overflow at line 2870

我当前的ifelse条件语句如下所示:

trndR$weeks <- ifelse(trndR$mymonth == "Apr" & trndR$variable == "IstWEEKRent", 1,
                ifelse(trndR$mymonth == "Apr" & trndR$variable == "IIndWEEKRent", 2,
                ifelse(trndR$mymonth == "Apr" & trndR$variable == "IIIrdWEEKRent", 3,
                ifelse(trndR$mymonth == "Apr" & trndR$variable == "IVthWEEKRent", 4,
                ifelse(trndR$mymonth == "May" & trndR$variable == "IstWEEKRent", 5,
                ifelse(trndR$mymonth == "May" & trndR$variable == "IIndWEEKRent", 6,

trndR是我的df的名称,条件可以扩展到48。

我发现我只能拥有最多50个嵌套的ifelse条件......但不太确定如何纠正这个问题。我读过有关应用功能的内容,但在这种情况下我不知道如何使用它。

2 个答案:

答案 0 :(得分:3)

1)试试这个:

mos <- month.abb[c(4:12, 1:3)] # Apr, May, ...., Dec, Jan, Feb, Mar
transform(trndR, weeks = 4 * (match(mymonth, mos)-1) + as.numeric(variable))

使用问题中发布的trndR进行此操作:

         FY  YEARMN       BRAND      variable  value mymonth weeks
1 2015-2016 2015.25 3M CAR CARE   IstWEEKRent      0     Apr     1
2 2015-2016 2015.25 CAR CARE 3M  IIndWEEKRent  17500     Apr     2
3 2015-2016 2015.25 CAR CARE 3M IIIrdWEEKRent  85000     Apr     3
4 2015-2016 2015.25 CAR CARE 3M  IVthWEEKRent 212500     Apr     4

即使行没有排序,即使缺少周数,这也应该有效。

1a)这个替代方案更短(只有一行),但可能不那么明确:

transform(trndR, weeks = 4*((match(mymonth, month.abb)-4) %% 12) + as.numeric(variable))

2)如果行已排序且没有丢失周数,那么这也可以正常工作

transform(trndR, weeks = 1:nrow(trndR))

答案 1 :(得分:1)

从数据的外观来看,您应该能够确保所有内容都处于正确的顺序,然后在特定的一周内调用每一行。例如(在G.Grothendieck向我指出<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.4/angular.min.js"></script> <table ng-app="" ng-init="names=['Bill','Billa','Billy']; ages=['10', '20', '30']"> <tr ng-repeat="name in names track by $index"> <td>{{ name }} is {{ ages[$index] }} years old.</td> </tr> </table>列是因素之后稍微编辑,他们的答案看起来比我的更整洁,但是如果有任何兴趣我还是会留在这里) :

variable

看起来您的数据包含一个财政年度,但如果没有,您可以重写上面的最后一行以在每个财政年度应用它(假设每个FY在您的数据集中完全表示):

# get a value from 1 to 4, representing the `variable` column numerically
trndR$weeks <- as.numeric( trndR$variable )

# now sort the dataframe by `YEARMN` and `weeks` respectively to make sure everything is in order
trndR <- trndR[ with( trndR, order( YEARMN, weeks ) ), ]

# and replace that new `weeks` column with a sequence
trndR$weeks <- seq_along( trndR$weeks )