2016-07-06 2 views
1

У меня есть data.frame, как показано ниже. Он имеет много строк и несколько значений в каждом столбцеr data.frame поворот и добавление строк

ID=c(466,469,471,480,509,513,515,517,518,519,520,521,453,455,463,474,477,479,481,482,484,489,496,497,500,503) 
name=c(rep("a",12),rep("b",14)) 
start=c(rep("2/13/2013",12),rep("3/6/2013",14)) 
end=c(rep("2/20/2013",12),rep("3/13/2013",14)) 
start=as.Date(start,"%m/%d/%Y") 
end=as.Date(end,"%m/%d/%Y") 

maint=data.frame(ID,name,start,end) 

> (maint[1,]) 
    ID name  start  end 
1 466 a 2013-02-13 2013-02-20 

Я хотел бы взять данные и преобразовать их следующим образом. Я предоставляю пример для первой строки из исходных данных, но я хочу, чтобы одно и то же было сделано со всеми строками исходных данных. Пожалуйста, сообщите, как это сделать.

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

ID name dates 
466 a 2/13/2013 
466 a 2/14/2013 
466 a 2/15/2013 
466 a 2/16/2013 
466 a 2/17/2013 
466 a 2/18/2013 
466 a 2/19/2013 
466 a 2/20/2013 

ответ

1

Вот уже метод в базовом R:

# get sequence of dates for each observation 
mydates <- Map(function(x, y) seq(x, y, by="days"), as.Date(df$start), as.Date(df$end)) 
# get number of days for each observation 
dates.length <- sapply(mydates, length) 

# build a new data.frame 
dfNew <- data.frame(ID=rep(df$ID, dates.length), 
        name=rep(df$name, dates.length), 
        dates=as.Date(unlist(mydates), origin=as.Date("1970-01-01")) 

В @ user2100721 ​​указывает в комментарии, функция Map может быть упрощена с помощью seq.Date непосредственно:

mydates <- Map(seq.Date, as.Date(df$start), as.Date(df$end), by="days") 

данные

df <- read.table(header=T, text="ID name  start  end 
1 466 a 2013-02-13 2013-02-20 
2 467 b 2011-02-13 2011-02-22", as.is=T) 
+0

@ user2100721 ​​Получил это. Спасибо за уловку – lmo

+0

Вы можете использовать 'seq.Date' внутри' Map' вместо определения функции. – user2100721

+0

Я общался с этим около 5 минут, прежде чем сдаться и перейти к анонимной функции. – lmo

2

Мы можем использовать data.table. Преобразуйте 'data.frame' в 'data.table' (setDT(maint)), сгруппированные по 'ID', name '(при условии, что для каждой комбинации имеется только одна строка), мы получаем seq' start 'to' end .

library(data.table) 
setDT(maint)[, .(dates = seq(start, end, by = "1 day")) , .(ID, name)] 
+0

Я попробовал свой метод в исходном файле csv, и я получаю сообщение об ошибке «Ошибка в is.finite (from): метод по умолчанию не реализован для типа« замыкание » – user2543622

+0

@ user2543622 Я не получаю никаких ошибок на основе Например, вы предоставили – akrun

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