【问题标题】:R, pivot_wider issueR,pivot_wider 问题
【发布时间】:2021-08-13 13:05:44
【问题描述】:

我有一个这样的数据框:

    df<-structure(list(Date = structure(c(17605, 18179, 17605, 18508, 
17626, 17837, 17963, 17900, 17823, 18008), class = "Date"), Patient = c("Doe, John", 
"Doe, John", "Scissorhands, Edward", "Coleman, Ronnie", "Cuomo, Governor", 
"Kent, Clark", "Wayne, Bruce", "Lane, Lois", "Gray, Dorian", 
"Gray, Dorian"), MRN = c(12345, 12345, 54321, 
65432, 765432, 9876, 87654, 111111, 
101010, 101010), DOB = structure(c(5254, 5254, -1561, 
-10629, 428, 3005, 3156, -2127, -5836, -5836), class = "Date"), 
    `ICD-10 Billed Procedure Code` = c("Detachment at Right Ring Finger, Mid, Open Approach", 
    "Detachment at Right Ring Finger, Low, Open Approach", "Detachment at Right Index Finger, Mid, Open Approach", 
    "Detachment at Left Hand, Complete 5th Ray, Open Approach", 
    "Detachment at Right Hand, Complete 5th Ray, Open Approach", 
    "Detachment at Right Little Finger, High, Open Approach", 
    "Detachment at Right Hand, Partial 1st Ray, Open Approach", 
    "Detachment at Left Index Finger, High, Open Approach", "Detachment at Right Index Finger, Low, Open Approach", 
    "Detachment at Left Index Finger, Low, Open Approach"), Admission = structure(c(0, 
    0, 0, 0, 1, 5, 2, 0, 0, 0), class = "difftime", units = "days")), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"), problems = structure(list(
    row = 456L, col = "Discharge Date", expected = "date like %m/%d/%Y", 
    actual = "c", file = "'Patients.csv'"), row.names = c(NA, 
-1L), class = c("tbl_df", "tbl", "data.frame")))

而且我想将其旋转得更宽,以便每位患者只有一排。我可以用这段代码做到这一点,它在我的数据的前十行(如您在上面看到的)上运行良好:

df<-df%>%pivot_wider(names_from = `ICD-10 Billed Procedure Code`,values_from = c(Date,Admission))

它会创建一堆列,其中包含患者进行每次手术的日期以及每次手术入院时长的信息。没关系。稍后我会将所有这些新列组织成我想要的。

当我尝试在我拥有的所有行(总共 497 行)上运行它时出现了我的问题,当我添加第 11 行时,您可以在此处看到它。

    df2<-structure(list(Date = structure(c(17605, 18179, 17605, 18508, 
    17626, 17837, 17963, 17900, 17823, 18008, 18008), class = "Date"), 
        Patient = c("Doe, John", 
"Doe, John", "Scissorhands, Edward", "Coleman, Ronnie", "Cuomo, Governor", 
"Kent, Clark", "Wayne, Bruce", "Lane, Lois", "Gray, Dorian", 
"Gray, Dorian", 
        "Gray, Dorian"), MRN = c(12345, 12345, 54321, 
65432, 765432, 9876, 87654, 111111, 
101010, 101010, 101010), DOB = structure(c(5254, 
        5254, -1561, -10629, 428, 3005, 3156, -2127, -5836, -5836, 
        -5836), class = "Date"), `ICD-10 Billed Procedure Code` = c("Detachment at Right Ring Finger, Mid, Open Approach", 
        "Detachment at Right Ring Finger, Low, Open Approach", "Detachment at Right Index Finger, Mid, Open Approach", 
        "Detachment at Left Hand, Complete 5th Ray, Open Approach", 
        "Detachment at Right Hand, Complete 5th Ray, Open Approach", 
        "Detachment at Right Little Finger, High, Open Approach", 
        "Detachment at Right Hand, Partial 1st Ray, Open Approach", 
        "Detachment at Left Index Finger, High, Open Approach", "Detachment at Right Index Finger, Low, Open Approach", 
        "Detachment at Left Index Finger, Low, Open Approach", "Detachment at Right Index Finger, Low, Open Approach"
        ), Admission = structure(c(0, 0, 0, 0, 1, 5, 2, 0, 0, 0, 
        0), class = "difftime", units = "days")), row.names = c(NA, 
    -11L), class = c("tbl_df", "tbl", "data.frame"), problems = structure(list(
        row = 456L, col = "Discharge Date", expected = "date like %m/%d/%Y", 
        actual = "c", file = "'Patients.csv'"), row.names = c(NA, 
    -1L), class = c("tbl_df", "tbl", "data.frame")))

我收到此错误:

所有应该为 NA 的单元格都变成了 NULL,日期格式变得很奇怪。

鉴于我大致知道导致它的原因,我认为这一定是两个“Dorian Gray”行共享相同的“程序代码”。 (我认为?如果我错了,请告诉我)问题是,这种情况会发生几次,我想我可以接受吗?最终,我会将输出压缩为: “Patient, MRN, DOB, Number_of_Surgeries, Total_Admission_Time”,但我想在将列浓缩为“手术次数”和“总入院时间”之前先解决这个 pivot_wider。

那么...我该如何解决这个错误?

【问题讨论】:

标签: r tidyverse


【解决方案1】:

对我来说,你的每个更宽的列都是"Detachment at Right Ring Finger, Mid, Open Approach""Detachment at Right Ring Finger, Low, Open Approach",这似乎很奇怪。对我来说,将其分成几列可能是有意义的,例如"Finger""Where""Approach" 等。

试试这个:

library(dplyr)
library(tidyr)
out <- df %>%
  mutate(strcapture("Detachment at ([^,]+), ?([^,]+), ?(.*)",
                    `ICD-10 Billed Procedure Code`,
                    list(Finger="", Where="", Approach=""))) %>%
  group_by(Patient) %>%
  mutate(rn = row_number()) %>%
  ungroup() %>%
  select(-`ICD-10 Billed Procedure Code`) %>%
  pivot_wider(
    c(Patient, MRN, DOB, Admission),
    names_from = "rn",
    values_from = c("Date", "Finger", "Where", "Approach"),
    names_glue = "{.value}_{rn}")
# out
# A tibble: 8 x 12
#   Patient                 MRN DOB        Admission Date_1     Date_2     Finger_1            Finger_2          Where_1          Where_2 Approach_1    Approach_2   
#   <chr>                 <dbl> <date>     <drtn>    <date>     <date>     <chr>               <chr>             <chr>            <chr>   <chr>         <chr>        
# 1 Doe, John             12345 1984-05-21 0 days    2018-03-15 2019-10-10 Right Ring Finger   Right Ring Finger Mid              Low     Open Approach Open Approach
# 2 Scissorhands, Edward  54321 1965-09-23 0 days    2018-03-15 NA         Right Index Finger  <NA>              Mid              <NA>    Open Approach <NA>         
# 3 Coleman, Ronnie       65432 1940-11-25 0 days    2020-09-03 NA         Left Hand           <NA>              Complete 5th Ray <NA>    Open Approach <NA>         
# 4 Cuomo, Governor      765432 1971-03-05 1 days    2018-04-05 NA         Right Hand          <NA>              Complete 5th Ray <NA>    Open Approach <NA>         
# 5 Kent, Clark            9876 1978-03-25 5 days    2018-11-02 NA         Right Little Finger <NA>              High             <NA>    Open Approach <NA>         
# 6 Wayne, Bruce          87654 1978-08-23 2 days    2019-03-08 NA         Right Hand          <NA>              Partial 1st Ray  <NA>    Open Approach <NA>         
# 7 Lane, Lois           111111 1964-03-06 0 days    2019-01-04 NA         Left Index Finger   <NA>              High             <NA>    Open Approach <NA>         
# 8 Gray, Dorian         101010 1954-01-09 0 days    2018-10-19 2019-04-22 Right Index Finger  Left Index Finger Low              Low     Open Approach Open Approach

作为美学补充,可以更好地对列进行分组:

cn <- colnames(out)
out[, cn[ order(grepl("[0-9]$", cn), gsub("\\D", "", cn)) ]]
# # A tibble: 8 x 12
#   Patient                 MRN DOB        Admission Date_1     Finger_1            Where_1          Approach_1    Date_2     Finger_2          Where_2 Approach_2   
#   <chr>                 <dbl> <date>     <drtn>    <date>     <chr>               <chr>            <chr>         <date>     <chr>             <chr>   <chr>        
# 1 Doe, John             12345 1984-05-21 0 days    2018-03-15 Right Ring Finger   Mid              Open Approach 2019-10-10 Right Ring Finger Low     Open Approach
# 2 Scissorhands, Edward  54321 1965-09-23 0 days    2018-03-15 Right Index Finger  Mid              Open Approach NA         <NA>              <NA>    <NA>         
# 3 Coleman, Ronnie       65432 1940-11-25 0 days    2020-09-03 Left Hand           Complete 5th Ray Open Approach NA         <NA>              <NA>    <NA>         
# 4 Cuomo, Governor      765432 1971-03-05 1 days    2018-04-05 Right Hand          Complete 5th Ray Open Approach NA         <NA>              <NA>    <NA>         
# 5 Kent, Clark            9876 1978-03-25 5 days    2018-11-02 Right Little Finger High             Open Approach NA         <NA>              <NA>    <NA>         
# 6 Wayne, Bruce          87654 1978-08-23 2 days    2019-03-08 Right Hand          Partial 1st Ray  Open Approach NA         <NA>              <NA>    <NA>         
# 7 Lane, Lois           111111 1964-03-06 0 days    2019-01-04 Left Index Finger   High             Open Approach NA         <NA>              <NA>    <NA>         
# 8 Gray, Dorian         101010 1954-01-09 0 days    2018-10-19 Right Index Finger  Low              Open Approach 2019-04-22 Left Index Finger Low     Open Approach

(我猜有更好的dplyr-esque 方法可以做到这一点,也许使用relocate。)

【讨论】:

  • 这个解决方案比我要求的效果还要好。我唯一奇怪的问题是,它似乎提供了一大堆相同的“MRN”列,这些列都一遍又一遍地说同样的事情。我会认为 MRN 总是一样的,我应该只得到一列。
  • 糟糕,是的,我不小心在旋转 args 中包含了 "MRN",它应该是一个 id...查看我的编辑 :-)
【解决方案2】:

如果您最终只需要汇总数据,我不明白为什么您首先需要这一步,您可以简单地:

library(dplyr)
df2 %>%
 group_by(Date, Patient, MRN, DOB) %>%
summarize(Number_of_Surgeries=length(unique(`ICD-10 Billed Procedure Code`)),
          Total_Admission_Time = sum(Admission))
# output
# 
# Date       Patient                 MRN DOB        Number_of_Surgeries Total_Admission_Time
# <date>     <chr>                 <dbl> <date>                   <int> <drtn>              
# 1 2018-03-15 Doe, John             12345 1984-05-21                   1 0 days              
# 2 2018-03-15 Scissorhands, Edward  54321 1965-09-23                   1 0 days              
# 3 2018-04-05 Cuomo, Governor      765432 1971-03-05                   1 1 days              
# 4 2018-10-19 Gray, Dorian         101010 1954-01-09                   1 0 days              
# 5 2018-11-02 Kent, Clark            9876 1978-03-25                   1 5 days              
# 6 2019-01-04 Lane, Lois           111111 1964-03-06                   1 0 days              
# 7 2019-03-08 Wayne, Bruce          87654 1978-08-23                   1 2 days              
# 8 2019-04-22 Gray, Dorian         101010 1954-01-09                   2 0 days              
# 9 2019-10-10 Doe, John             12345 1984-05-21                   1 0 days              
#10 2020-09-03 Coleman, Ronnie       65432 1940-11-25                   1 0 days 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-29
    • 1970-01-01
    • 2020-06-18
    • 2020-10-15
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多