Как изменить данные панели с широких на длинные, а также как создать временную переменную и добавить ее - PullRequest
0 голосов
/ 25 марта 2019

У меня возникли проблемы с работой моего кода.Ранее я задавал вопрос на этом сайте, который не решил мою проблему полностью. «Изменение формы данных HRS с широкой на длинную и создание переменной времени»

На этот раз я попытался очень четко и точно описать свои данные.Это выглядит примерно так: все переменные начинаются с «r», за которым следует число от 1 до 10, за которым следует измеренная переменная.Единственная переменная, которая не начинается с «r», это id-tracker, который называется «idhhpn».

Это пример структуры моих данных, но не совсем моих данных.Мой файл данных очень большой, и я не могу опубликовать его здесь:

df <- structure(list(data = structure(1:4, .Label = c("Ind_1", "Ind_2", 
    "Ind_3", "Ind_4"), class = "factor"), r1weight = c(56, 76, 87, 64
    ),r10weight = c(57, 75, 88, 66), r1height = c(186, 176, 187, 165), r10height = c(187L, 
    173L, 185L, NA), r1bmi = c(23L, 22L, 25L, 21L), r10bmi = c(24L, 23L, 
    29L, 23), r1logass = c(8L, 4L, NA, 2L), r10logass = c(7, 5L, 2, 
    4L), r1vigact = c(1, 0, 1, 1), r10vigact = c(0,0,0,1), idhhpn = c(1,2,3,4), rmale = c(0,0,1,0), rhighs = c(1,1,1,0), rcoll = c(1,0,1,0) ), class = 
    "data.frame", row.names = c(NA, 
    -4L)) 



data       r1weight r10weight r1height r10height r1bmi r10bmi r1logass r10logass r1vigact r10vigact idhhpn rmale rhighs rcoll
1 Ind_1       56        57      186       187    23     24        8         7        1         0      1     0      1     1
2 Ind_2       76        75      176       173    22     23        4         5        0         0      2     0      1     0
3 Ind_3       87        88      187       185    25     29       NA         2        1         0      3     1      1     1
4 Ind_4       64        66      165        NA    21     23        2         4        1         1      4     0      0     0
`

У меня есть 23 переменные, все наблюдаемые 10 раз (по одной в год в течение 10 лет).У меня также есть несколько манекенов, таких как rmale, rhispanic, rblack, rHS, rGED, rCollege и т. Д.

Я хочу преобразовать это в следующее:

dflong <- structure(list(time = structure(1:12, .Label = c("1", "...","10","1", "...","10","1", "...","10", "1", "...","10"), 
     class = "factor"), idhhpn = c(1,1,1,2,2,2,3,3,3,4,4,4), W = c(56,"...", 57,76,"...",75,87,"...",88,64,"...",66),
     H = c(186,"...",187,176,"...",173,187,"...",185,165,"...","..."), BMI = c(23,"...",24,22,"...",23,25,"...",29,21,"...",23),
     logA = c(8,"...",7,4,"...",5,"...","...",2,2,"...",4), vigact = c(1,"...",0,0,"...",0,1,"...",0,1,"...",1),
     rmale = c(0,"...",0,0,"...",0,1,"...",1,0,"...",0), rhighs = c(1,"...",1, 1,"...",1,1, "...",1,0,"...",0),
     rcoll = c(1,"...",1,0,"...",0,1,"...",1,0,"...",0)),
     class = "data.frame", row.names = c(NA, -12L))`

   time idhhpn W   H BMI logA vigact rmale rhighs rcoll
1     1      1  56 186  23    8      1     0      1     1
2   ...      1 ... ... ...  ...    ...   ...    ...   ...
3    10      1  57 187  24    7      0     0      1     1
4     1      2  76 176  22    4      0     0      1     0
5   ...      2 ... ... ...  ...    ...   ...    ...   ...
6    10      2  75 173  23    5      0     0      1     0
7     1      3  87 187  25  ...      1     1      1     1
8   ...      3 ... ... ...  ...    ...   ...    ...   ...
9    10      3  88 185  29    2      0     1      1     1
10    1      4  64 165  21    2      1     0      0     0
11  ...      4 ... ... ...  ...    ...   ...    ...   ...
12   10      4  66 ...  23    4      1     0      0     0

Там, где есть переменная времени от 1 до 10 для каждого человека для каждой переменной, как показано на рисунке.

Где я пропустил отметки времени 2-9 (для удобства чтения)

В настоящее время у меня есть следующий код, который, я уверен, является почти правильным.

HRSdata_melt <- HRSdata %>% gather(time,ind,-HRSdata) %>%
                    mutate(time=gsub("r([1-10])", "\\1_",time)) %>%
                    separate(time, into = c("time", "idhhpn")) %>% 
                    spread(idhhpn, ind)

, но он дает мне следующую ошибку, которая, я думаю, связана с какой-то незначительной ошибкой.

enter image description here

enter image description here

Вот пример dput(head(HRSdata)) enter image description here

1 Ответ

0 голосов
/ 25 марта 2019

Мы можем использовать от dplyr::matches до gather по всем столбцам, где за r следует цифра или более, а затем что-нибудь, например r1weight, r2weight, ..., r10weight и т. Д. Затем mutate иspread

library(dplyr)
library(tidyr)
df %>% gather(key,val,matches('r\\d+.*')) %>% 
       mutate(time=gsub('r(\\d+).*','\\1',key), key=sub('(r\\d+)(.*)','\\2',key)) %>%
       spread(key,val)

r(\\d+).* получить одну или несколько цифр после r в качестве первой группы и вернуть ее, используя \\1

(r\\d+)(.*)получить что-нибудь после (r\\d+) в качестве второй группы и вернуть это, используя \\2
...