2016-07-09 305 views
2

我有以下的數據幀替代與多個條件嵌套ifelse語句的一長串

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 

我的月柱,從四月有個月到Mar ...每個月在我的數據集中有4個星期,這是在列變量中給出的。我想創建爲FY四月每週數日 - 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條件...但不太確定如何糾正這個問題。我讀了關於應用函數,但不知道如何在這種情況下使用它。

+0

該數據是否有排序?您顯示的數據看起來像是每星期有一行一致,在這種情況下,行號可能足夠用於「周」列。 – rosscova

回答

2

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)如果行排序,並沒有缺失周那麼這會工作作爲well

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

'as.numeric'如何將字符串轉換爲數字?我可以看到這可能是可能的,但我無法得到它(只是這種轉換)爲我工作。 – rosscova

+0

他們不是性格 - 他們是因素。嘗試'str(trndR)' –

+0

啊,我沒有注意到!使問題變得更容易!謝謝。 – rosscova

1

從數據的外觀來看,您應該能夠確保所有內容都按照正確的順序排列,然後在特定的一週內調用每一行。例如(G.Grothendieck指給我看後小幅編輯的variable列因素,他們的回答似乎比我更整潔,但我會在這裏呢,以防離開這個是任何權益):

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

它看起來像你的數據包含一個財政年度,但如果沒有,你可以把上面的最後一行來應用它每財政年度(假設每個財政年度在你的數據集是完全代表):

library(data.table) 
setDT(trndR)[ , weeks := seq_len(48), by = FY ] 
+0

非常感謝....我試過你的解決方案...然而,seq_along填充了列週數,序列號從1到1256,而我一直在尋找一個從1到48的範圍(考慮每週4個星期)的數字。非常感謝......您的解決方案確實幫助我瞭解了另一種解決方案.....自從上個早晨以來,我一直在努力解決這個問題。在應用ifelse之前,我正在按FY進行子集劃分。 – Apricot

+1

你使用了最後一節(帶'data.table')嗎?這應該避免你談論的長序列。無論如何,我很高興你找到了解決方案。 – rosscova