#r #list #date #format #character
#r #Список #Дата #формат #символ
Вопрос:
Я слышал действительно глупый формат вывода из наблюдений, которые я должен прочитать с помощью scan.
Вот фрагмент из (data.dat), где я пометил заголовок и блоки данных:
06.02.2014 # header
PNP
-0,005
00:05#587 # values
00:15#591
23:50#587
23:55#587
07.02.2014 # header
PNP
-0,005
00:10#587 # values
00:15#590
23:55#590
24:00#593
08.02.2014 # header
PNP
-0,005
00:05#590 # value
00:10#595
00:15#600
23:50#600
23:55#607
Проблемы заключаются в:
- У меня есть дата за несколько лет с разрешением 5 минут,
- каждый день имеет собственный заголовок (постоянной длины), начинающийся с даты и двух дополнительных записей,
- длина временного ряда (формат HH: ММ # значение) для каждого дня не является постоянной, существуют пробелы в данных (не показаны в примере)
Моя цель — data.frame формы дата, время, значение.
Итак, мне нужен цикл или что-то в этом роде, который анализирует отдельные элементы списка (вывод из scan (file=data.dat, what =» «) как символ). Поскольку временные блоки имеют разную длину, я хотел бы установить мои ежедневные данные, начиная с даты, пропустив некоторые дополнительные элементы заголовка, а затем разделить элементы time #value списка, который был выведен с помощью
crap <- scan(file = data.dat, what=" ") # import as list
strsplit хорошо работает с
tmp <- strsplit(crap[4:8], split="#")
df <- data.frame(date=as.Date(crap[1],format = "%d.%m.%Y"), time=sapply(tmp, "[[", 1), W=sapply(tmp, "[[", 2))
Однако я понятия не имею, как анализировать элементы из списка (как символы), если они имеют допустимый формат даты.
Приветствия!
Ответ №1:
У меня есть решение, но оно может быть очень специфичным для заданного вами вопроса и того, что я интерпретировал.
Сначала прочитайте данные и удалите PNP and -0,005
их из данных.
crap <- read.table(file = "data.dat",comment.char = " ")
a <- as.vector(crap$V1)
a <- a[-grep("PNP|-0,005",x = a)]
Теперь я извлекаю даты, содержащиеся в векторе a
dateId <- grep(".",x=a,fixed=T)
uniquedate <- as.matrix(a[dateId])
> uniquedate
[,1]
[1,] "06.02.2014"
[2,] "07.02.2014"
[3,] "08.02.2014"
Теперь я создаю вектор дат той же длины, что и количество значений в наборе данных, повторяя даты для количества значений, присутствующих в соответствующей дате.
len <- length(dateId)
dateRepVal <- c(diff(dateId)-1,(length(a) - dateId[len]))
dates <- unlist(sapply(1:len,FUN = function(x){rep(uniquedate[x],dateRepVal[x])}))
Все остальные элементы, ожидающие дату в нашем наборе "a"
данных, представляют собой пару время-значение. используя эту информацию, теперь я получаю время и значение с помощью strsplit
функции, а затем создаю фрейм данных.
timeVal <- strsplit(a[-dateId],split = "#")
time <- sapply(timeVal, "[[", 1)
val <- sapply(timeVal, "[[", 2)
DF <- data.frame(date = dates,time=time,val=val)
Окончательный требуемый результат выглядит следующим образом.
>DF
date time val
1 06.02.2014 00:05 587
2 06.02.2014 00:15 591
3 06.02.2014 23:50 587
4 06.02.2014 23:55 587
5 07.02.2014 00:10 587
6 07.02.2014 00:15 590
7 07.02.2014 23:55 590
8 07.02.2014 24:00 593
9 08.02.2014 00:05 590
10 08.02.2014 00:10 595
11 08.02.2014 00:15 600
12 08.02.2014 23:50 600
13 08.02.2014 23:55 607
Надеюсь, это решит проблему.
Комментарии:
1. Однако у меня есть два изменения. даты <- unlist(sapply(1:len,FUN = function(x){rep(uniquedate[x],dateRepVal[x])})) #nVal DF <- data.frame(дата = c(даты),время = время, значение = значение)
2. Рад, что это помогло.