2016-06-21 72 views
0

我有一列日期,我嘗試爲每行創建一個年份列表。例如,這是我的數據的幾行:將多個年份範圍轉換爲R中的年份列表

1997-2001 
1994 
2007-2009; 2013-2015; 2016 
2007-2008; 2014 

例如,第一行我想包含一個清單:1997年,1998年,1999年,2000年和2001年。第二排我想要的清單包含1994年。對於第三行,我想要一個包含:2007年,2008年,2009年,2013年,2014年,2015年和2016年,等等這樣的列表。有沒有辦法做到這一點?

+0

你的列保存着什麼數據類型?字符串還是什麼?你可以在這裏「輸」你的專欄嗎? – 989

+0

下面是一些解決方案,但我不知道哪個最好推薦:http://r.789695.n4.nabble.com/convert-delimited-strings-with-ranges-to-numeric-td4673763.html – leekaiinthesky

回答

3

這是醜陋的,但它能夠完成任務:

lapply(strsplit(df$date,'\\s*;\\s*'),function(x) unlist(lapply(strsplit(x,'-'),function(y) { z <- as.integer(y); if (length(z)==1L) z else z[1L]:z[2L]; }))); 
## [[1]] 
## [1] 1997 1998 1999 2000 2001 
## 
## [[2]] 
## [1] 1994 
## 
## [[3]] 
## [1] 2007 2008 2009 2013 2014 2015 2016 
## 
## [[4]] 
## [1] 2007 2008 2014 
## 

數據

df <- data.frame(date=c('1997-2001','1994','2007-2009; 2013-2015; 2016','2007-2008; 2014'), 
stringsAsFactors=F); 

注意:如果您的輸入向量是一個因素,而不是一個字符向量,那麼在將其傳遞給最初的strsplit()呼叫之前,您必須將其包裝在as.character()中。

+0

如果我想爲for循環中的每一行創建一個列表(因爲我想用給定行中的其他變量做其他事情),我還需要使用lapply嗎?謝謝! –

+0

如果您的迭代器是行索引,您可以在循環中使用'lapply()'調用的結果。在循環的每次迭代中單獨運行分割/排序邏輯沒有任何好處;你也可以預先計算整個事物,然後根據需要訪問每個元素。 – bgoldst

+0

當我運行上面的代碼時,出現以下錯誤:strsplit中的錯誤(歷史$ Term,「\\ s *; \\ s *」):非字符參數 –

0

bgoldst的答案解決了這個問題,但這裏有另一種方法可以做到。

您可以使用gsub您分號轉換成逗號和破折號冒號像這樣(其中df是數據幀,x是包含數據的列):

df$x<-gsub("-",":",df$x) 
df$x<-gsub(";",",",df$x) 

這將使您:

1997:2001 
1994 
2007:2009, 2013-2015, 2016 
2007:2008, 2014 

然後用一個for循環來評估所有這些表達式:

years<-list() 
for(i in 1:nrow(df)){ 
    years[i]<-list(eval(parse(text=paste("c(",df$x[i],")")))) 
} 

如上所述,如果您的輸入是因素而非字符的矢量,則需要用替換as.character(df$x[i])

相關問題