Расширение фрейма данных путем копирования значений из условно идентифицированной строки в новые столбцы - PullRequest
1 голос
/ 23 января 2020

У меня есть набор данных для мета-анализа, который содержит данные до теста в наборе столбцов, данные после теста в другом наборе столбцов и один столбец для условия (т. Е. Обработки [Condition == 1] против контроля [Условие == 0]). Мне нужно расширить этот набор данных таким образом, чтобы я создал новый набор столбцов для данных до и после контрольных наблюдений и данных после испытаний, который размещается рядом с данными исходных данных лечения. Эти данные сгруппированы по идентификатору. Это означает, что мне нужно условно скопировать только наблюдения, которые являются «контрольными», в набор столбцов вместе с «обработкой» наблюдений, но внутри каждой группы идентификаторов.

Я знаю, что это неприятный способ описать это, поэтому Вот пример набора данных, который у меня есть:

data_before.df <- data.frame(ID = c(1,1,1,2,2,2,3,3,3),
                         Condition = c(0,1,2,0,1,2,0,1,2),
                         Pre_M = c(1,2,3,4,5,6,7,8,9),
                         Post_M = c(90,80,70,60,50,40,30,20,10))
data_before.df

А вот что мне нужно сделать:

data_after.df <- data.frame(ID = c(1,1,2,2,3,3),
                            Condition = c(1,2,1,2,1,2),
                            Pre_M = c(2,3,5,6,8,9),
                            Post_M = c(80,70,50,40,20,10),
                            Control_Pre_M = c(1,1,4,4,7,7),
                            Control_Post_M = c(90,90,60,60,30,30))
data_after.df

1 Ответ

2 голосов
/ 23 января 2020

Вот один вариант с dplyr. После группировки по «ID» создайте два новых столбца с «Control» в качестве части столбца, циклически перебирая столбец, заканчивающийся «M», и поднабор значения, где «Condition» равно 0, ungroup и filter из строки, где «Условие» равно 0

library(dplyr)
library(stringr)
data_before.df %>%
    group_by(ID) %>%
    mutate_at(vars(ends_with('M')), list(Control = ~.[Condition == 0])) %>%
    ungroup %>%
    filter(Condition != 0) %>%
    rename_at(vars(ends_with('Control')), ~
             str_replace(., '(.*)_Control', 'Control_\\1'))
# A tibble: 6 x 6
#     ID Condition Pre_M Post_M Control_Pre_M Control_Post_M
#  <dbl>     <dbl> <dbl>  <dbl>         <dbl>          <dbl>
#1     1         1     2     80             1             90
#2     1         2     3     70             1             90
#3     2         1     5     50             4             60
#4     2         2     6     40             4             60
#5     3         1     8     20             7             30
#6     3         2     9     10             7             30

Или вариант с merge из base R

merge(subset(data_before.df, Condition != 0), 
   subset(data_before.df, Condition == 0, 
        select = c("ID", "Pre_M", "Post_M")), by = 'ID')

Или соединение с data.table

library(data.table)
setDT(data_before.df)[Condition != 0][data_before.df[Condition == 0, 
   .(ID, Control_Pre_M = Pre_M, Control_Post_M = Post_M)], on  = .(ID)]
#    ID Condition Pre_M Post_M Control_Pre_M Control_Post_M
#1:  1         1     2     80             1             90
#2:  1         2     3     70             1             90
#3:  2         1     5     50             4             60
#4:  2         2     6     40             4             60
#5:  3         1     8     20             7             30
#6:  3         2     9     10             7             30
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...