Повторные меры в грязном формате, нужна помощь, чтобы привести в порядок - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть очень большой набор данных, содержащий недельные веса, которые были закодированы с неделей обучения и весом при этом посещении.Есть некоторые пропущенные посещения, и данные в настоящее время не выровнены.

df <- data.frame(ID=1:3, Week_A=c(6,6,7), Weight_A=c(23,24,23), Week_B=c(7,7,8), 
                 Weight_B=c(25,26,27), Week_C=c(8,9,9), Weight_C=c(27,26,28)) 

df
  ID Week_A Weight_A Week_B Weight_B Week_C Weight_C
1  1      6       23      7       25      8       27
2  2      6       24      7       26      9       26
3  3      7       23      8       27      9       28

Я хотел бы выровнять данные по номеру недели (идеальный вывод ниже).

df_ideal <- data.frame (ID=1:3, Week_6=c(23,24,NA), Week_7=c(25,26,23), 
                        Week_8=c(27,NA,27), Week_9=c(NA,26,28))

df_ideal
  ID Week_6 Week_7 Week_8 Week_9
1  1     23     25     27     NA
2  2     24     26     NA     26
3  3     NA     23     27     28

Я был бы признателен за помощь в этом, даже если бы нашел отправную точку для манипулирования этими данными в более удобном для управления формате.

Ответы [ 4 ]

0 голосов
/ 18 сентября 2018

В базе R это двойной reshape, сначала к длинной, а затем обратно к широкой по другой переменной:

tmp <- reshape(df, idvar="ID", varying=lapply(c("Week_","Weight_"), grep, names(df)),
               v.names=c("time","Week"), direction="long")
reshape(tmp, idvar="ID", direction="wide", sep="_")

#    ID Week_6 Week_7 Week_8 Week_9
#1.1  1     23     25     27     NA
#2.1  2     24     26     NA     26
#3.1  3     NA     23     27     28
0 голосов
/ 18 сентября 2018

Тидиверс решение:

df <- data.frame(ID=1:3, 
                 Week_A=c(6,6,7), 
                 Weight_A=c(23,24,23), 
                 Week_B=c(7,7,8), 
                 Weight_B=c(25,26,27),
                 Week_C=c(8,9,9),
                 Weight_C=c(27,26,28))

library(tidyverse)
df_long <- df %>% gather(key="v", value="value", -ID) %>% 
  separate(v, into=c("v1", "v2")) %>% 
  spread(v1, value) %>% 
  complete(ID, Week) %>% 
  arrange(Week, ID)

df_long
# A tibble: 12 x 4
#      ID  Week v2    Weight
#   <int> <dbl> <chr>  <dbl>
# 1     1     6 A         23
# 2     2     6 A         24
# 3     3     6 <NA>      NA
# 4     1     7 B         25
# 5     2     7 B         26
# 6     3     7 A         23
# 7     1     8 C         27
# 8     2     8 <NA>      NA
# 9     3     8 B         27
#10     1     9 <NA>      NA
#11     2     9 C         26
#12     3     9 C         28

df_wide <- df_long %>% select(-v2) %>% 
  spread(Week, Weight, sep="_")
df_wide
# A tibble: 3 x 5
#     ID Week_6 Week_7 Week_8 Week_9
#  <int>  <dbl>  <dbl>  <dbl>  <dbl>
#1     1     23     25     27     NA
#2     2     24     26     NA     26
#3     3     NA     23     27     28

Лично я бы продолжал использовать df_long вместо df_wide, так как это tidy фрейм данных, а df_wide - нет.

0 голосов
/ 18 сентября 2018

Другое tidyverse решение с использованием двойного gather с окончательным spread

df %>%
    gather(k, v, -ID, -starts_with("Weight")) %>%
    separate(k, into = c("k1", "k2")) %>%
    unite(k1, k1, v) %>%
    gather(k, v, starts_with("Weight")) %>%
    separate(k, into = c("k3", "k4")) %>%
    filter(k2 == k4) %>%
    select(-k2, -k3, -k4) %>%
    spread(k1, v)
#  ID Week_6 Week_7 Week_8 Week_9
#1  1     23     25     27     NA
#2  2     24     26     NA     26
#3  3     NA     23     27     28
0 голосов
/ 18 сентября 2018

Вот возможный подход с использованием пакета data.table

library(data.table)
#convert into a data.table
setDT(df)

#convert into a long format
mdat <- melt(df, id.vars="ID", measure.vars=patterns("^Week", "^Weight", cols=names(df)))

#pivot into desired output
ans <- dcast(mdat, ID ~ value1, value.var="value2")

ans выход:

   ID  6  7  8  9
1:  1 23 25 27 NA
2:  2 24 26 NA 26
3:  3 NA 23 27 28

И если вам действительно нужна "Week_" в именах столбцов, вы можете использовать

setnames(ans, names(ans)[-1L], paste("Week_", names(ans)[-1L]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...