Как поменять местами столбцы в зависимости от типа данных?

Пример данных приведен ниже (данные являются поддельными, а не реальными):

Ключ Индикатор смерти Дата смерти Точная дата смерти Причина смерти 00 Живой 02 Смерть шлюха Да 25.09.2011 Н00 03 Живой 09 Смерть шлюха Да J189 28.08.2015 07 Смерть негодяев 06.12.2018 Да С20

Из таблицы видно, что типы данных в одних и тех же столбцах не совпадают. 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

опубликуйте свое решение как решение, не добавляйте его к своему вопросу, так позже читателям будет труднее его найти.

Mark 26.04.2024 05:41
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Даты непростые, но вы можете проверить пакет lubridate. Какие ошибки выдает код R? Если вас останавливают ошибки, я бы предложил начать даты как символьный столбец, собрать все данные в одном столбце, а затем проанализировать значения NA. Как только все будет в правильном формате, приведите столбец к формату даты. Поскольку столбец символов примет ваши изменения, вы сможете выполнить любую необходимую очистку. Проблема с приведением к формату даты на первом этапе заключается в том, что часто такие общие функции преобразования, как as.date(), очень требовательны. Если какое-либо значение имеет неверный формат, все завершится неудачей и выдаст ошибку. Так что, если вы увлеклись этим, попробуйте выполнить это преобразование с помощью anytime на последнем шаге и посмотрите, не получишь ли вы лучших результатов.

Я попробовал anytime, `lubridate, and base r::as.date()` и все еще не смог проанализировать некоторые форматы дат (или некоторые форматы, которые я пропустил). Вот почему я хочу использовать два других формата («Y», «N», ICD10) вместо даты.

doraemon 26.04.2024 05:35
Ответ принят как подходящий

Есть несколько разных способов сделать это. Для меня самый простой способ, который не требует создания нового вектора трижды, — это создать именованный список в 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)

Примечания:

  1. Вы сказали, что у вас возникли проблемы с разбором дат. Было бы полезно, если бы вы привели несколько примеров дат, которые вам сложно проанализировать.
  2. Ваши данные все еще нуждаются в некоторой очистке — например, "Y" и "N" должны быть TRUE и FALSE. Также если данные являются данными о смерти, то имеет смысл удалить Живые, они ничего не добавляют. Также заготовки должны NA.

Я забыл упомянуть одну важную вещь: формат даты может не совпадать, например. «05.01.2010» также может отображаться в столбцах дат. Ваша идея великолепна без использования фиктивных переменных!

doraemon 26.04.2024 05:44

@doraemon ах, ладно. Это только один пример. Если мы используем grep, нам нужны все варианты. Я ответил на слишком много вопросов, где пользователь спрашивает A, я решаю A, затем мне говорят, что оно тоже должно соответствовать B, я меняю его, чтобы оно тоже соответствовало B, а затем повторяю для C, D и т. д.

Mark 26.04.2024 07:33

05.01.2010 невозможно проанализировать без контекста, поскольку это может быть 1 мая или 5 января.

Mark 26.04.2024 07:34

Другие вопросы по теме

Создайте столбцы с количеством дней в зависимости от количества существующих столбцов
Попытка вычислить индекс площади листа в пакете LidR приводит к ошибке «Обнаружены повторяющиеся элементы»
Предупреждение о переформулировании R dplyr против ошибки на основе набора данных
Преобразование символьной строки с диапазонами в числовой вектор в R
Неверная логика с регулярными выражениями и числовыми диапазонами
Игнорирование добавленного содержимого; prependContent нельзя использовать в вызове рендеринга Shiny
Как использовать `bslib::accordion_panel_update()` для обновления заголовка панели
Проблема с использованием n_distinct в sparklyr для подсчета различных значений в зависимости от условия
Как я могу выполнить повторную перекрестную проверку для модели Кокса с эластичной сетью в R?
Извлечение записей в фрейме данных, соответствующих n наименьшим положительным значениям и n наибольшим отрицательным значениям определенной переменной в r