You could just convert your dates to character then convert them back to dates at the end:
(person <- df %>%
select(hh_id, bday_01:gender_02) %>%
mutate_each(funs(as.character), contains('bday')) %>%
gather(key, value, -hh_id) %>%
separate(key, c("key", "per_num"), sep = "_") %>%
spread(key, value) %>%
mutate(bday=ymd(bday)))
hh_id per_num bday gender
1 1 01 2015-03-09 M
2 1 02 1985-09-11 F
3 2 01 1989-02-11 F
4 2 02 2000-08-15 F
Alternatively, if you use Date
instead of POSIXct
, you could do something like this:
(person <- df %>%
select(hh_id, bday_01:gender_02) %>%
gather(per_num1, gender, contains('gender'), convert=TRUE) %>%
gather(per_num2, bday, contains('bday'), convert=TRUE) %>%
mutate(bday=as.Date(bday)) %>%
mutate_each(funs(str_extract(., '\d+')), per_num1, per_num2) %>%
filter(per_num1 == per_num2) %>%
rename(per_num=per_num1) %>%
select(-per_num2))
Edit
The warning you're seeing:
Warning: attributes are not identical across measure variables; they will be dropped
arises from gathering the gender columns, which are factors and have different level vectors (see str(df)
). If you were to convert the gender columns to character or if you were to synchronize their levels with something like,
df <- mutate(df, gender_02 = factor(gender_02, levels=levels(gender_01)))
then you will see that the warning goes away when you execute
person <- df %>%
select(hh_id, bday_01:gender_02) %>%
gather(key, value, contains('gender'))