Нужно сделать столбцы, показывающие, какие идентификаторы назначены этим столбцам ... не знаю, как описать - PullRequest
1 голос
/ 15 марта 2019

Каждый пациент назначается двум врачам. Всего три доктора. Мои данные выглядят так:

>df
Dr1    Dr2    PatientID
Chris  John   5
John   Mike   24
Mike   John   28

Мне нужно 3 столбца (по одному на доктора), показывающих, кто их пациенты

Chris   John   Mike
5       5      24
        24     28
        28

Я пытаюсь играть с melt(), но безуспешно.

Ответы [ 3 ]

2 голосов
/ 15 марта 2019

Фреймы данных являются прямоугольными. То, что вы хотите, не является прямоугольным, поэтому давайте вместо этого сделаем list:

with(reshape2::melt(df, id.vars = "PatientID"), split(PatientID, value))
# $Chris
# [1] 5
# 
# $John
# [1] 24  5 28
# 
# $Mike
# [1] 28 24

Используя эти данные:

df = read.table(text = "Dr1    Dr2    PatientID
Chris  John   5
John   Mike   24
Mike   John   28", header = T)
2 голосов
/ 15 марта 2019

Базовый вариант R, аналогичный решению Грегора

unstack(reshape(dat, idvar = "PatientID", varying = 1:2, direction = "long", sep = ""),
        PatientID ~ Dr)
# $Chris
# [1] 5
# 
# $John
# [1] 24  5 28
# 
# $Mike
# [1] 28 24

Данные

text <- "Dr1    Dr2    PatientID
Chris  John   5
John   Mike   24
Mike   John   28"

dat <- read.table(text = text, stringsAsFactors = FALSE, header = TRUE)
2 голосов
/ 15 марта 2019

Создание фрейма данных с неровными столбцами (т. Е. Столбцами различной длины) немного сложнее, но вот попытка.Обратите внимание на использование оператора %$% magrittr:

library(tidyverse)

df <- read.table(text = 'Dr1    Dr2    PatientID
Chris  John   5
                 John   Mike   24
                 Mike   John   28', header = T)

list.per.dr <- df %>% 
  gather(doc, name, -PatientID) %>% 
  select(-doc) %$% 
  split(PatientID, name) 

$Chris
[1] 5

$John
[1] 24  5 28

$Mike
[1] 28 24

Теперь у нас есть объект списка, в котором указаны пациенты, назначенные каждому врачу.Чтобы преобразовать это во фрейм данных, нам нужно выровнять их длины:

max_patients <- max(lengths(list.per.dr))

df.new <- list.per.dr %>% 
  lapply(function(x) c(x, rep(NA, max_patients - length(x)))) %>% 
  as.data.frame()

  Chris John Mike
1     5   24   28
2    NA    5   24
3    NA   28   NA
...