2014-02-07 6 views
-1

Я работаю с 1-минутной информацией о временных интервалах солнечных фотоэлектрических интервалов, где исходная отметка времени имела даты и время, объединенные вместе. Я использовал sub() для разделения даты и времени, а затем использовал cbind(), чтобы добавить их в мой фрейм. Сначала все выглядит нормально, однако я хотел бы создать небольшую проверку ошибок, которая гарантирует, что даты и время соответствуют исходной строке, и если они не совпадают, тогда она вернет индексы строк для дальнейшего устранения неполадок. Моя идея - использовать grepl +, чтобы идентифицировать совпадения/несоответствия. В приведенном ниже коде показано, с чем я работаю.Использование grepl и для проверки точной последовательности строк с данными временных рядов

> head(data2) 
    dates times   datetime use..kW.  gen..kW. Grid..kW. 
1 12/31/2013 23:58 12/31/2013 23:58 1.463883 -0.003050000 1.463883 
2 12/31/2013 23:57 12/31/2013 23:57 1.940267 -0.003450000 1.940267 
3 12/31/2013 23:56 12/31/2013 23:56 1.934417 -0.003466667 1.934417 
4 12/31/2013 23:55 12/31/2013 23:55 1.996050 -0.003550000 1.996050 
5 12/31/2013 23:54 12/31/2013 23:54 2.009883 -0.003566667 2.009883 
6 12/31/2013 23:53 12/31/2013 23:53 2.009967 -0.003516667 2.009967 
Solar..kW. Solar...kW. 
1 -0.003050000   0 
2 -0.003450000   0 
3 -0.003466667   0 
4 -0.003550000   0 
5 -0.003566667   0 
6 -0.003516667   0 

> a <- grepl("23:56", data2[, 3]) 

> which(a == TRUE) 
    [1]  3 1443 2883 4323 5763 7203 8643 10083 11523 

результаты которого() выше, соответствуют всем строкам с «23:56» в строке в столбце даты и времени. Я только скопировал одну строку вектора возврата, чтобы сэкономить место ...

Я знаю, что для моей проверки я хотел бы идентифицировать ложные случаи, TRUE используется пока только для иллюстрации. Проблема, с которой я сталкиваюсь, связана с использованием более чем одной символьной строки в grepl(), потому что я не просто хочу сделать это с одним значением времени, но и для каждой строки в моем фреймворке. Я пробовал использовать mapply с grepl, но у моего DataFrame есть 478 933 наблюдения, поэтому он уходил в путь. Mapply + grepl выглядел так:

mapply(grepl, data2$dates, data2$datetime) 

Я использовал ту же самую функцию mapply только с диапазоном наблюдений (200). Когда установлено значение TRUE, я получаю индексы для 200 строк, с FALSE я получаю целое число (0), которое, как я понимаю, будет означать, что мои данные точны, поэтому все это может быть ненужным ... Но теперь я инвестирован в проблему из больше перспективы обучения/упражнений, и это принесет мне пользу в работе с более крупными наборами данных.

Извините за длинный вопрос. Заранее благодарим за ваши предложения.

Часть 2:

Мои извинения за не предоставление воспроизводимых данных. Мои данные слишком велики, чтобы опубликовать весь dataframe до SO. Также @ G.Grothendieck, я разделяю строку datetime, потому что я собираюсь использовать tapply или split, чтобы взять распределение выборки для каждого временного интервала, т. Е. У меня будет 1440 «ведер», которые соответствуют каждой минуте в один день. Каждое ведро будет заполнено наблюдениями в этот промежуток времени со всего года.

Вот новая версия (data3), которая является главой data2. Я изменил значение data3 [3,2] как «23:57», которое не соответствует времени в столбце данных, поэтому мы можем использовать это для тестирования обоих ваших решений. Сначала идут Джастин, а затем Г. Гротендик.

> data3 <- head(data2) 
> data3[3,2] <- "23:57" 
> data3 
     dates times   datetime use..kW.  gen..kW. Grid..kW. Solar..kW. 
1 12/31/2013 23:58 12/31/2013 23:58 1.463883 -0.003050000 1.463883 -0.003050000 
2 12/31/2013 23:57 12/31/2013 23:57 1.940267 -0.003450000 1.940267 -0.003450000 
3 12/31/2013 23:57 12/31/2013 23:56 1.934417 -0.003466667 1.934417 -0.003466667 
4 12/31/2013 23:55 12/31/2013 23:55 1.996050 -0.003550000 1.996050 -0.003550000 
5 12/31/2013 23:54 12/31/2013 23:54 2.009883 -0.003566667 2.009883 -0.003566667 
6 12/31/2013 23:53 12/31/2013 23:53 2.009967 -0.003516667 2.009967 -0.003516667 
    Solar...kW. 
1   0 
2   0 
3   0 
4   0 
5   0 
6   0 
> all(paste(data3$dates, data3$times) == data3$datetime) 
[1] FALSE 
> which(paste(data3$dates, data3$times) != data3$datetime) 
[1] 3 
> with(data3, which(format(datetime) != paste(dates, times))) 
[1] 3 

Таким образом, они оба ведут к тому же результату ... Однако, когда я использовал решение G.Grothendieck по всей dataframe (data2) он сказал, что строки 840: 24279 были несовпадения. Вот первые две строки вывода:

> with(data2, which(format(datetime) != paste(dates, times))) 
    [1] 840 841 842 843 844 845 846 847 848 849 850 851 
    [13] 852 853 854 855 856 857 858 859 860 861 862 863 

Я положил первые 6 строк несовпадений в новую DF (Data4). Затем применяется каждый из ваших решений снова ...

> data4 
     dates times  datetime use..kW. gen..kW. Grid..kW. Solar..kW. 
840 12/31/2013 9:59 12/31/2013 9:59 4.480733 5.948300 -1.4675667 5.948300 
841 12/31/2013 9:58 12/31/2013 9:58 4.503950 5.832533 -1.3285833 5.832533 
842 12/31/2013 9:57 12/31/2013 9:57 4.516283 5.739600 -1.2233167 5.739600 
843 12/31/2013 9:56 12/31/2013 9:56 4.906783 5.677033 -0.7702500 5.677033 
844 12/31/2013 9:55 12/31/2013 9:55 5.951183 5.621617 0.3295667 5.621617 
845 12/31/2013 9:54 12/31/2013 9:54 6.226417 5.596517 0.6299000 5.596517 
    Solar...kW. 
840 5.948300 
841 5.832533 
842 5.739600 
843 5.677033 
844 5.621617 
845 5.596517 
> all(paste(data4$dates, data4$times) == data4$datetime) 
[1] TRUE 
> which(paste(data4$dates, data4$times) != data4$datetime) 
integer(0) 
> with(data4, which(format(datetime) != paste(dates, times))) 
integer(0) 
> 

Это еще раз показывает, что ваши решения одинаковы, но я запутался, почему, когда я использую G.Grothendieck по всей dataframe (data2), почему он выдает 840: 24279 как несоответствие. Дайте мне знать, достаточно ли этих данных.

+0

Я не понимаю, что вы пытаетесь сделать там. Почему бы вам не превратить ваши даты в «POSIXct»? Вы даже можете использовать пакет lubridate, если базовые функции не предлагают достаточно функциональности для ваших вкусов. – Roland

+0

Позвольте мне повторить: вам не нужно разделить ваши даты, и вы не должны делать это, используя шаблон. R поставляется с определенными функциями для работы с датами, и все, что вы хотите сделать, можно легко выполнить с помощью этих функций и, возможно, одного из пакетов временных рядов. – Roland

+0

Roland, спасибо за ввод. Теперь я понимаю, почему использование регулярных выражений не самое лучшее. Я преобразовал свое datetime в POSIXct и теперь пытаюсь выяснить, как: (1) подмножество только «дневных» наблюдений, т.е. между 7:00 и 21:00 (2) подмножество/разделение данных на 5 и 15-минутные интервалы , Это не очень подходит в контексте моего первоначального вопроса, поэтому я, вероятно, сделаю еще одну запись в ближайшее время. – stokeinfo

ответ

0

Вы можете использовать только векторизованные логические сравнения ...

all(paste(data2$dates, data2$times) == data2$datetime) 

Если вернуться TRUE, если все совпадает и FALSE иначе. Вы также можете обернуть его в which и вместо этого использовать !=, чтобы увидеть строки, в которых вещи не совпадают.

which(paste(data2$dates, data2$times) != data2$datetime) 

Наконец, я стараюсь избегать регулярных выражений (и sub) всякий раз, когда это возможно. Вместо этого, я хотел бы использовать что-то вроде этого:

splits <- strsplit(data2$datetime, ' ') 
data2$dates <- sapply(splits, '[', 1) 
data2$times <- sapply(splits, '[', 2) 
+0

Сладкий, спасибо! Это круто. Я думаю, на самом деле нет необходимости перебирать каждую строку. – stokeinfo

+0

@stokeinfo FWIW, почти никогда не нужно перебирать каждую строку! – Justin

0

Это даст номера строк, где date и time не соответствуют DateTime

with(data2, which(format(datetime) != paste(date, time))) 

Вы не могли бы нуждаться в format часть, но мы можем» t, поскольку данные не были предоставлены в воспроизводимой форме в вопросе.

Кроме того, рассмотрите, действительно ли вам нужно разделить datetime на первом месте.

+0

Это решение пугает меня, потому что в нем говорится, что 413 000 наблюдений не совпадают. Решение Джастина выше дало ИСТИНУЮ, которая показала бы, что все в порядке. Любые мысли о расхождениях между этими двумя решениями? – stokeinfo

+1

Вам действительно нужно предоставить свои данные в воспроизводимой форме, задавая вопросы о SO. Без этого мы просто догадываемся. Например, формат может создавать часовой пояс? Попробуйте отправить 'dput (head (data2))'. Также, как уже упоминалось, реальное решение, скорее всего, не должно быть разделено на дату и время. –

+0

Я все запомню @ G.Grothendieck сказал! пока мы не узнаем, как выглядят ваши данные, все это делается в темноте. – Justin