Как изменить упорядоченную группу столбцов, имена которых лежат в диапазоне значений?

Я работаю с приведенным ниже фреймом данных, который содержит данные переменных столбцов для каждого года в 1997-2010 годах и годовой диапазон, описанный столбцами «min» и «max».

Я хочу, чтобы мои значения в каждом столбце года были изменены на 1, если год находится в диапазоне от минимального до максимального. Как бы я это сделал?

library(tidyverse)

    df <- structure(list(`1997` = c(1, 0, 0, 0, 0, 0), `1998` = c(0, 0, 
0, 0, 0, 0), `1999` = c(0, 0, 0, 0, 0, 0), `2000` = c(0, 0, 0, 
1, 0, 1), `2001` = c(0, 0, 0, 1, 0, 1), `2002` = c(0, 0, 0, 0, 
0, 1), `2003` = c(0, 0, 0, 0, 0, 1), `2004` = c(0, 0, 0, 0, 0, 
1), `2005` = c(0, 0, 0, 1, 0, 1), `2006` = c(0, 0, 1, 0, 0, 1
), `2007` = c(0, 0, 1, 1, 0, 1), `2008` = c(0, 0, 1, 1, 0, 1), 
    `2009` = c(0, 0, 1, 1, 0, 1), `2010` = c(0, 0, 1, 1, 0, 1
    ), min = c(1997, 1998, 2006, 2000, 1997, 2000), max = c(1998, 
    1998, 2010, 2010, 2008, 2010)), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"), .Names = c("1997", "1998", "1999", "2000", 
"2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", 
"2009", "2010", "min", "max"))

Я пробовал использовать mutate_at из пакета dplyr и создать вектор для назначения этим столбцам (и манипулировать позже), но я борюсь с этим углом. Как мне изменить приведенный ниже вызов на funs(), чтобы я мог изменить все 0 в этом диапазоне на 1?

 for (i in 1:nrow(df)){
    if (!is.na(df[i,]$min) & !is.na(df[i,]$max)){
      df[i,] <- df[i,] %>% 
        mutate_at(vars(`1997`:`2010`), funs(min:max))
    }
  } 

person dad    schedule 22.02.2018    source источник
comment
Интересный вопрос. Надеюсь, вы не возражаете против окончательного data.frame, показывающего TRUE/FALSE вместо 1/0   -  person MKR    schedule 22.02.2018


Ответы (1)


Одним из решений может быть использование sapply и mapply, как показано ниже. Я также использовал функцию between из dplyr.

Вместо 0 и 1 мое решение показывает FALSE/TRUE. Надеюсь, что с OP все в порядке.

#df has been taken from OP
sapply(names(df)[1:(ncol(df)-2)], 
      function(x)mapply(between, as.numeric(x), df$min, df$max)) %>%
       as.data.frame() %>% cbind(df[,c("min","max")])

   1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  min  max
1  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 1997 1998
2 FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 1998 1998
3 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE 2006 2010
4 FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE 2000 2010
5  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE 1997 2008
6 FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE 2000 2010
person MKR    schedule 22.02.2018