Определите значения первого столбца для каждого идентификатора и работайте на основе этого значения - PullRequest
0 голосов
/ 28 июня 2018

Определение значений первого столбца для каждого идентификатора и их замена на основе этого значения

У меня есть следующий df со многими столбцами:

input <- data.frame(ID = c(1,1,1,1,1,2,2,3,3,3),
Obs1 = c(1,0,1,1,0,0,1,1,0,1),
Obs2 = c(0,1,1,0,1,1,1,1,1,0),
Control1 = c(1,1,2,2,2,1,2,1,1,2),
Control2 = c(1,2,2,2,3,1,1,1,2,2))

Я хотел бы изменить значения столбцов 'Control'. Если первое значение «Obs» для идентификатора равно 0, тогда я должен вычесть -1 для всей группы идентификаторов:

result <- data.frame(ID = c(1,1,1,1,1,2,2,3,3,3),
Obs1 = c(1,0,1,1,0,0,1,1,0,1),
Obs2 = c(0,1,1,0,1,1,1,1,1,0),
Control1 = c(1,1,2,2,2,0,1,1,1,1),
Control2 = c(0,1,1,1,2,1,1,1,2,2))

Способ получения первых значений obs для идентификатора следующий:

i <- 1 
aux <- vector("list", 2)

for (i in 2:3)
aux [[i]] <- input[!duplicated(input$ID), i]

С этим списком, как я могу изменить столбцы 'Control'? (У меня больше 100)

1 Ответ

0 голосов
/ 28 июня 2018

Используя data.table, я сначала преобразовал бы ваши данные в длинный формат (при объединении всех столбцов "Obs" и "Control" в одни и те же столбцы с помощью функции patterns), выполнил вычисления и преобразовал обратно в широкий. Это будет масштабироваться до любого количества пар.

library(data.table)
library(magrittr)

# The patterns of the columns we will be working with
cols <- c("Obs", "Control")

res <- 
  # convert to data.table and add row index so we can dcast back afterwards
  setDT(input)[, rowind := .I] %>% 

  # Convert to long format and combine all Obs and Controls into two columns
  melt(., id = c("rowind", "ID"), patterns(cols), value.name = cols) %>%

  # Reduce 1 from Control in case the first value is zero
  .[, Control := Control - first(Obs == 0), by = .(ID, variable)] %>%

  # Convert back to wide format
  dcast(., ID + rowind ~ variable, value.var = cols, sep = "") %>%

  # Remove the row index
  .[, rowind := NULL]

res
#     ID Obs1 Obs2 Control1 Control2
#  1:  1    1    0        1        0
#  2:  1    0    1        1        1
#  3:  1    1    1        2        1
#  4:  1    1    0        2        1
#  5:  1    0    1        2        2
#  6:  2    0    1        0        1
#  7:  2    1    1        1        1
#  8:  3    1    1        1        1
#  9:  3    0    1        1        2
# 10:  3    1    0        2        2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...