Пример данных приведен ниже (данные являются поддельными, а не реальными):
Из таблицы видно, что типы данных в одних и тех же столбцах не совпадают. Date Death должно быть в формате даты; Exact date of death должен содержать только Y, N или пробел; Death Cause должен быть в строке (т. е. коде ICD).
Я забыл упомянуть одну важную вещь: формат даты может не совпадать, например. «01-05-2010», «01 мая 2010» также могут отображаться в столбцах дат. Я попытался выполнить базовую очистку данных:
Питон:
import pandas as pd
death_y_n = death['Date Death'][pd.to_datetime(death['Date Death'], \
format='%d/%m/%Y',
errors = 'coerce')\
.isnull()]
death_disease_case = death['Exact date of death'][~((death['Exact date of death'].isin(['Y','N']))\
|(death['Exact date of death'].isnull()))]
death['Death Cause'][~pd.to_datetime(\
death['Death Cause'], \
format='%d/%m/%Y', errors = 'coerce')\
.isnull()] = \
death_disease_case
death['Date Death'][pd.to_datetime(\
death['Date Death'], \
format='%d/%m/%Y', errors = 'coerce')\
.isnull()] = \
death_to_date[pd.to_datetime(\
death['Date Death'], \
format='%d/%m/%Y', errors = 'coerce')\
.isnull()]
death['Exact date of death'][~death['Exact date of death'].isin(['Y','N'])] = \
death_y_n[~death['Exact date of death'].isin(['Y','N'])]
death['Death Cause'][pd.to_datetime(\
death['Date Death'], \
format='%d/%m/%Y', errors = 'coerce')\
.isnull()] = \
death_y_n[pd.to_datetime(\
death['Date Death'], \
format='mixed', errors = 'coerce')\
.isnull()]
Р:
library(tidyverse)
library(magrittr)
library(anytime)
library(Hmisc)
death_to_date = anytime(death$`Death Cause`) %>% as.character
death_y_n = death$`Date Death`[is.na(as_date(death$`Date Death`))]
death_disease_case = death$`Exact date of death`[death$`Exact date of death` %nin% c('Y','N')]
death$`Death Cause`[!is.na(as_date(death$`Death Cause` ))] = death_disease_case[!is.na(as_date(death$`Death Cause` ))]
death$`Date of Registered Death`[is.na(as_date(death$`Date Death`))] = death_to_date[is.na(as_date(death$`Date Death`))]
death$`Exact date of death`[death$`Exact date of death` %nin% c('Y','N')] = death_y_n[death$`Exact date of death` %nin% c('Y','N')]
Однако из-за нескольких форматов даты некоторые форматы даты невозможно успешно проанализировать. Есть ли способ поменять местами столбцы без использования to_datetime()/anytime()?
Я новичок в Python, если я допустил какие-либо ошибки, укажите на них! Спасибо.
Обновлено:
Мое решение на Python:
import pandas as pd
#for death date variable save as exact date of death:'Y'/'N'
death_to_date_index_exact = (death['Date Death'].isin(['Y','N']))
death_to_date_exact = death['Date Death'][death_to_date_index_exact]
#for death cause variable save as date of death
death_cause_index_date = (~death['Death Cause'].str.contains('^[A-Za-z].*[0-9]$',na=True))
death_cause_date = death['Death Cause'][death_cause_index_date]
#for exact date of death variable save as death cause
death_exact_index_cause = (death['Exact date of death'].str.contains('^[A-Za-z].*[0-9]$',na=False))
death_exact_cause = death['Exact date of death'][death_exact_index_cause]
death['Date Death'][death_cause_index_date] = death_cause_date
death['Exact date of death'][death_to_date_index_exact] = death_to_date_exact
death['Death Cause'][death_exact_index_cause] = death_exact_cause
#Convert the date in death cause into empty
death['Death Cause'][~death['Death Cause'].str.contains('^[A-Za-z].*[0-9]$',na=True)] = np.nan






Даты непростые, но вы можете проверить пакет lubridate. Какие ошибки выдает код R? Если вас останавливают ошибки, я бы предложил начать даты как символьный столбец, собрать все данные в одном столбце, а затем проанализировать значения NA. Как только все будет в правильном формате, приведите столбец к формату даты. Поскольку столбец символов примет ваши изменения, вы сможете выполнить любую необходимую очистку. Проблема с приведением к формату даты на первом этапе заключается в том, что часто такие общие функции преобразования, как as.date(), очень требовательны. Если какое-либо значение имеет неверный формат, все завершится неудачей и выдаст ошибку. Так что, если вы увлеклись этим, попробуйте выполнить это преобразование с помощью anytime на последнем шаге и посмотрите, не получишь ли вы лучших результатов.
Я попробовал anytime, `lubridate, and base r::as.date()` и все еще не смог проанализировать некоторые форматы дат (или некоторые форматы, которые я пропустил). Вот почему я хочу использовать два других формата («Y», «N», ICD10) вместо даты.
Есть несколько разных способов сделать это. Для меня самый простой способ, который не требует создания нового вектора трижды, — это создать именованный список в R, а затем расширить его, как показано ниже:
library(tidyverse)
df |>
mutate(sorted = pmap(list(Date.Death, Exact.date.of.death, Death.Cause), \(...) {out <- list()
for (x in c(...)) { # for each row of the three columns above
if (x %in% c("Y", "N", NA)) { # we do this one first, otherwise the NAs throw things off
out$Exact.date.of.death <- x
} else if (grepl("/", x)) {
out$Date.Death <- x
} else {
out$Death.Cause <- x
}
}
out
}), .keep = "unused") |> # drop the columns we used (i.e. Date.Death, Exact.date.of.death, Death.Cause)
unnest_wider(sorted) # then unnest the named list column, making new versions of them!
Выход:
# A tibble: 5 × 5
Key Death.indicator Exact.date.of.death Date.Death Death.Cause
<chr> <chr> <chr> <chr> <chr>
1 Alive NA NA NA NA
2 Death hos Y 25/9/2011 N00
3 Alive NA NA NA NA
4 Death hos Y 28/8/2015 J189
5 Death nonhos Y 12/6/2018 C20
Данные:
df <- read.table(text = "Key Death.indicator Date.Death Exact.date.of.death Death.Cause
00 Alive NA NA NA NA
02 Death hos Y 25/9/2011 N00
03 Alive NA NA NA NA
09 Death hos Y J189 28/8/2015
07 Death nonhos 12/6/2018 Y C20", header=TRUE)
Примечания:
"Y" и "N" должны быть TRUE и FALSE. Также если данные являются данными о смерти, то имеет смысл удалить Живые, они ничего не добавляют. Также заготовки должны NA.Я забыл упомянуть одну важную вещь: формат даты может не совпадать, например. «05.01.2010» также может отображаться в столбцах дат. Ваша идея великолепна без использования фиктивных переменных!
@doraemon ах, ладно. Это только один пример. Если мы используем grep, нам нужны все варианты. Я ответил на слишком много вопросов, где пользователь спрашивает A, я решаю A, затем мне говорят, что оно тоже должно соответствовать B, я меняю его, чтобы оно тоже соответствовало B, а затем повторяю для C, D и т. д.
05.01.2010 невозможно проанализировать без контекста, поскольку это может быть 1 мая или 5 января.
опубликуйте свое решение как решение, не добавляйте его к своему вопросу, так позже читателям будет труднее его найти.