(вопрос о списках в R)
Я работаю с очень большим набором данных, где у меня есть столбец даты, который принимает одну из двух форм:
- тип даты 1: «ММ / ДД / ГГГГ ЧЧ: ММ: СС AM»
- тип даты 2: «ММ / ДД / ГГГГЧ: ММ: СС AM - ММ / ДД / ГГГГ ЧЧ: ММ: СС AM»
Мне нужно разделить этот столбец в зависимости от того, есть ли тире (тип 2), и поместить их в два столбца («Дата 1» и «Дата 2»). Если я столкнусь со строкой с датой типа 1, тогда дата просто займет «Дата 1», а «Дата 2» будет просто NA
.
Вот что я ищу - конвертируйте что-то похожее на это:
c(
rep("8/20/2018 9:18:45 AM", 15),
rep("8/20/2018 9:18:45 AM - 8/12/2018 9:18:45 AM", 15)
)
К этому:
data.frame(
Date1 = c(rep("8/15/2018 9:18:45 AM", 15), rep("8/20/2018 9:18:45 AM", 15)),
Date2 = c(rep(NA, 15), rep("8/12/2018 9:18:45 AM", 15))
)
# output
# Date1 Date2
# 1 8/15/2018 9:18:45 AM <NA>
# 2 8/15/2018 9:18:45 AM <NA>
# 3 8/15/2018 9:18:45 AM <NA>
# 4 8/15/2018 9:18:45 AM <NA>
# 5 8/15/2018 9:18:45 AM <NA>
# 6 8/15/2018 9:18:45 AM <NA>
# 7 8/15/2018 9:18:45 AM <NA>
# 8 8/15/2018 9:18:45 AM <NA>
# 9 8/15/2018 9:18:45 AM <NA>
# 10 8/15/2018 9:18:45 AM <NA>
# 11 8/15/2018 9:18:45 AM <NA>
# 12 8/15/2018 9:18:45 AM <NA>
# 13 8/15/2018 9:18:45 AM <NA>
# 14 8/15/2018 9:18:45 AM <NA>
# 15 8/15/2018 9:18:45 AM <NA>
# 16 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 17 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 18 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 19 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 20 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 21 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 22 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 23 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 24 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 25 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 26 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 27 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 28 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 29 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
# 30 8/20/2018 9:18:45 AM 8/12/2018 9:18:45 AM
Я хочу, чтобы первый подэлемент списка занимал столбец Date1
, а второй подэлемент (если он существует) занимал столбец Date2
. Если второго элемента нет, я хочу, чтобы строка Date2
была NA
.
Моя первая попытка - создать новый список, в котором я использую условие. Если длина подэлемента всего одна, я создаю второй подэлемент и устанавливаю его на NA
.
dates = c(
c(
rep("8/20/2018 9:18:45 AM", 15),
rep("8/20/2018 9:18:45 AM - 8/12/2018 9:18:45 AM", 15)
)
)
# create the date split. Split the text based on the dash
dates_split = strsplit(dates, " - ")
# note where the correct dates are. date_split[[15]] as one sub element and date_split[[16]] has two
dates_split[[15]];dates_split[[16]]
# so far so good
# create a conditional where if there is only one date (one sub element), set the second sub element to zero.
for(i in 1:length(dates_split)){
if(length(dates_split[i]) == 1){
dates_split[[i]][2] = NA
} else {}
}
# the above loop does not behave as expected. The dates_split[[16]][2] is now gone (it turned to NA)
# create a vector for Date1 and Date2
Date1 = unlist(lapply(dates_split, "[[", 1))
Date2 = unlist(lapply(dates_split, "[[", 2))
# put each date type in their appropriate column
date_df = data.frame(
Date1 = Date1,
Date2 = Date2
)
# second column is all NA's. Where did the second sub elements go?
Мой предыдущий скрипт для меньшего набора данных сделал что-то вроде этого, чтобы обойти это:
dates = strsplit(dates, " - ")
# this takes forever to do. Is there a way to do this without using a loop??
for(i in 1:nrow(dates_split)){
date_df$Date1 = dates[[i]][1]
date_df$Date2 = dates[[i]][2]
}
Выше не очень эффективно. Реальный набор данных содержит более миллиона строк, поэтому его загрузка займет целую вечность.
Есть ли какой-нибудь совет, как изменить этот шаг, чтобы я создал NA
для второго подэлемента без непреднамеренного превращения всего в NA
?
# create a conditional where if there is only one date (one sub element), set the second sub element to zero.
for(i in 1:length(dates_split)){
if(length(dates_split[i]) == 1){
dates_split[[i]][2] = NA
} else {}
}
# the above loop does not behave as expected. The dates_split[[16]][2] is now gone (it turned to NA)
Спасибо!