2016-06-21 4 views
0

У меня есть столбец дат, из которых я пытаюсь создать список лет для каждой строки. Например, это несколько рядов моих данных:Преобразование нескольких диапазонов лет в список лет в R

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

Например, для первой строки я хочу список, содержащий: 1997, 1998, 1999, 2000 и 2001 для второй строки я хочу список содержащий только 1994 год. Для 3-й строки я хочу список, содержащий: 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); 

Примечание: Если входной вектор является фактором, в отличие от вектора символов , тогда вам придется обернуть его в as.character(), прежде чем передать его в начальный вызов strsplit().

+0

если я хочу создать список для каждой строки в цикле for (потому что я хочу делать другие вещи с другими переменными в данной строке), мне все еще нужно использовать lapply? благодаря! –

+0

Вы можете использовать результат вызова 'lapply()' в вашем цикле, если ваш итератор является индексом строки. Нет никакой пользы для индивидуального запуска логики разделения/последовательности в каждой итерации цикла; вы могли бы также прекомпилировать все это, а затем просто получить доступ к каждому элементу по мере необходимости. – bgoldst

+0

, когда я запускаю ваш код выше, я получаю следующую ошибку: Ошибка в strsplit (история $ Term, "\\ s *; \\ s *"): несимвольный аргумент –

0

Ответ bgoldst разрешил проблему, но вот еще один способ сделать это.

Вы можете использовать gsub для преобразования с запятой в запятые и тир в двоеточие, как так (где ФР кадр данных и х столбец, содержащий данные):

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

который даст вам:

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

Затем используйте для цикла, чтобы оценить все эти выражения:

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

Как и выше, если ваш вход представляет собой вектор факторов, а не символов, вам нужно будет заменить df$x[i] на as.character(df$x[i]).

Смежные вопросы