Данные в длинном и широком формате, необходимо преобразовать в длинные в R - PullRequest
0 голосов
/ 28 ноября 2018

Я работаю с набором данных в обоих форматах.Это выглядит так:

ID week1 week2 week3 ... week12  
1   2     NA     NA  ...  NA  
1   NA    3      NA  ...  NA
1   NA    NA     3   ...  NA
...
1   NA    NA     NA  ...  4
2   4     NA     NA  ...  NA
2   NA    5      NA  ...  NA
2   NA    NA     3   ...  NA

Я изо всех сил пытаюсь теперь преобразовать это в исключительно длинный формат для анализа.Я хочу настроить его как:

ID week value
1   1    2
1   2    3
1   3    3
...
1   12   4
2   1    4
2   2    5
2   3    3

Может кто-нибудь дать какие-либо предложения для этого в R, пожалуйста?Я пробовал reshape2 и dplyr / tidyr, но получаю слишком много наблюдений, когда выбираю переменную ID.

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

1) набор Используя wide, показанный воспроизводимо в примечании 1 в конце, используйте gather для преобразования wide в длинную форму, отбросьте строки NA и сортируйте.

library(dplyr)
library(tidyr)

wide %>%
  gather("week", "value", -ID) %>%
  drop_na %>%
  arrange(ID, week)

предоставление:

  ID  week value
1  1 week1     2
2  1 week2     3
3  1 week3     3
4  1 week4     4
5  2 week1     4
6  2 week2     5
7  2 week3     3

2) изменение формы Использование только базы R:

varying <- list(value = 2:5)
long <- na.omit(reshape(wide, dir = "long", timevar = "week", 
  varying = varying, v.names = names(varying)))[1:3]
long[order(long$ID, long$week), ]

предоставление:

    ID week value
1.1  1    1     2
2.2  1    2     3
3.3  1    3     3
4.4  1    4     4
5.1  2    1     4
6.2  2    2     5
7.3  2    3     3

3) data.table Используя varying из (2), мы можем использовать melt из data.table.Обратите внимание, что мы могли бы либо указать id.vars или measure.vars, но в комментариях было указано, что мы можем обобщить это на несколько переменных, а подход measure.vars обобщает.

library(data.table)
longDT <- na.omit(melt(as.data.table(wide), measure.vars = varying, 
  variable.name = "week"))
setkey(longDT, ID, week)
longDT

давая:

   ID  week value
1:  1 week1     2
2:  1 week2     3
3:  1 week3     3
4:  1 week4     4
5:  2 week1     4
6:  2 week2     5
7:  2 week3     3

Примечание 1

Входные данные, используемые в воспроизводимой форме:

Lines <- "
ID week1 week2 week3 week4
1   2     NA     NA   NA  
1   NA    3      NA   NA
1   NA    NA     3    NA
1   NA    NA     NA   4
2   4     NA     NA   NA
2   NA    5      NA   NA
2   NA    NA     3    NA"
wide <- read.table(text = Lines, header = TRUE)

Примечание 2

Относительно наличия нескольких переменных данных.melt таблицы поддерживает это.Предположим, у нас есть следующее:

Lines2 <- "
ID week1var1 week1var2 week2var1 week2var2 week3var1 week3var2 week4var1 week4var2
1 1 2 20 NA NA NA NA NA NA
2 1 NA NA 3 30 NA NA NA NA
3 1 NA NA NA NA 3 30 NA NA
4 1 NA NA NA NA NA NA 4 40
5 2 4 40 NA NA NA NA NA NA
6 2 NA NA 5 50 NA NA NA NA
7 2 NA NA NA NA 3 30 NA NA"
wide2 <- read.table(text = Lines, header = TRUE)

library(data.table)

varying2 <- split(names(wide2)[-1], 
  sub("(.*\\d)(\\D.*)", "\\2", names(wide2)[-1]))

longDT2 <- na.omit(melt(as.data.table(wide2), measure.vars = varying2, 
  variable.name = "week"))
setkey(longDT2, ID, week)
longDT2

, дающее:

   ID week var1 var2
1:  1    1    2   20
2:  1    2    3   30
3:  1    3    3   30
4:  1    4    4   40
5:  2    1    4   40
6:  2    2    5   50
7:  2    3    3   30
0 голосов
/ 28 ноября 2018

Как насчет этого:

library(dplyr)

# small data sample
df <- read.table(text = 'ID week1 week2 week3 week4  
1   2     NA     NA    NA  
1   NA    3      NA    NA
1   NA    NA     3     NA
1   NA    NA     NA    4
2   4     NA     NA    NA
2   NA    5      NA    NA
2   NA    NA     3     NA', header = T)

df %>% 
   data.table::melt(id.vars = 'ID') %>% 
   na.omit()
...