Как лучше создать новую переменную по сравнению с `ifelse` в R? - PullRequest
0 голосов
/ 27 марта 2019

Я работаю с: - набор данных панели - 10 периодов времени

Мне нужно создать фиктивную переменную RL, которая равна 1 (TRUE) навсегда, если фиктивная переменная RS была 1 один раз.

другими словами: Новая переменная RL (охватывающая 10 периодов) должна быть 1 в t и всех последующих периодах, если RS равнялась 1 в периоде t-1. Если TRUE не произошло в RS и RS равно 0 (FALSE), тогда RL также должно быть 0.

Как только TRUE происходит в RS в период t, тогда RL должно быть 1 и далее (в t + 1, t + 2, t + 3, t + 4 ..., t + конец панели).

Моя проблема в том, что FALSE не правильно читается как 0, а как NA.

Я использовал ifelse, но это дает мне слишком много пробелов:

    df$r_1RL  <- rep(0,nrow(df)) # is = 0 cause noone can retire in t-1 since "RS0" doesn't exists
    df$r_2RL  <- ifelse(  df$r_1RS == 1, 1, ifelse(df$r_1RS == 0, 0, NA))
    df$r_3RL  <- ifelse( (df$r_1RS == 1 | df$r_2RS == 1), 1, ifelse( (df$r_1RS == 0 | df$r_2RS == 0), 0, NA))
    df$r_4RL  <- ifelse( (df$r_1RS == 1 | df$r_2RS == 1 | df$r_3RS == 1), 1, ifelse( (df$r_1RS == 0 | df$r_2RS == 0 | df$r_3RS == 0), 0, NA)) 
    df$r_5RL  <- ifelse( (df$r_1RS == 1 | df$r_2RS == 1 | df$r_3RS == 1 | df$r_4RS == 1 ), 1, ifelse( (df$r_1RS == 0 | df$r_2RS == 0 | df$r_3RS == 0 | df$r_4RS == 0), 0, NA))
    and so on... up to 10RL


   df <- structure(list(r_1RS = c(FALSE, FALSE, FALSE, FALSE, FALSE, NA
    ), r_2RS = c(FALSE, NA, FALSE, FALSE, FALSE, NA), r_3RS = c(FALSE, 
    FALSE, FALSE, FALSE, FALSE, NA), r_4RS = c(FALSE, FALSE, FALSE, 
    FALSE, NA, FALSE), r_5RS = c(FALSE, TRUE, FALSE, FALSE, NA, FALSE
    ), r_6RS = c(FALSE, FALSE, FALSE, FALSE, NA, TRUE), r_7RS = c(FALSE, 
    FALSE, FALSE, FALSE, NA, FALSE), r_8RS = c(TRUE, FALSE, FALSE, 
    FALSE, FALSE, FALSE), r_9RS = c(FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE), r_10RS = c(FALSE, FALSE, TRUE, FALSE, NA, FALSE), r_1RL = c(0, 
    0, 0, 0, 0, 0), r_2RL = c(0, 0, 0, 0, 0, NA), r_3RL = c(0, NA, 
    0, 0, 0, NA), r_4RL = c(0, NA, 0, 0, 0, NA), r_5RL = c(0, NA, 
    0, 0, NA, NA), r_6RL = c(0, 1, 0, 0, NA, NA), r_7RL = c(0, 1, 
    0, 0, NA, 1), r_8RL = c(0, 1, 0, 0, NA, 1), r_9RL = c(1, 1, 0, 
    0, NA, 1), r_10RL = c(1, 1, 0, 0, NA, 1)), row.names = c(NA, 
    -6L), class = c("tbl_df", "tbl", "data.frame"))

Здесь вы можете видеть, как только истина произойдет в RS, RL будет 1 после. Но есть две проблемы: во-первых, 1 в r_10RL должен быть NA, а r_7RL должен иметь 0 и , а не NA's

enter image description here

красный кружок NA должен быть 0, а желтый кружок 1 должен быть NA

1 Ответ

1 голос
/ 27 марта 2019

Это кажется очень хакерским, и мне это не нравится, но оно работает с вашими примерами данных.Возможно, вы могли бы взять общую идею и сделать ее более эффективной.Дайте мне знать, если у вас возникнут какие-либо проблемы!

# Using the first 10 columns of your dput dataframe
df <- df[1:10]
> df
# A tibble: 6 x 10
  r_1RS r_2RS r_3RS r_4RS r_5RS r_6RS r_7RS r_8RS r_9RS r_10RS
  <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl> 
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE  FALSE FALSE 
2 FALSE NA    FALSE FALSE TRUE  FALSE FALSE FALSE FALSE FALSE 
3 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE  
4 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE 
5 FALSE FALSE FALSE NA    NA    NA    NA    FALSE FALSE NA    
6 NA    NA    NA    FALSE FALSE TRUE  FALSE FALSE FALSE FALSE 

# Createing a copy for the new columns
df2 <- df

# There may be other ways to handle NA's but you mentioend you want them
# as zero so this should work for you
df2[is.na(df2)] <- 0

# Changing all values after TRUE to 1
df2 <- data.frame(t(apply(df2, 1, function(x) as.numeric(cumsum(x) > 0))))

# Chaning the names
names(df2) <- sub("RS", "RL", names(df), fixed = T)

# Combining the columns
> cbind(df, df2)
  r_1RS r_2RS r_3RS r_4RS r_5RS r_6RS r_7RS r_8RS r_9RS r_10RS r_1RL r_2RL r_3RL r_4RL r_5RL r_6RL r_7RL r_8RL r_9RL r_10RL
1 FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE  FALSE     0     0     0     0     0     0     0     1     1      1
2 FALSE    NA FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  FALSE     0     0     0     0     1     1     1     1     1      1
3 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE   TRUE     0     0     0     0     0     0     0     0     0      1
4 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  FALSE     0     0     0     0     0     0     0     0     0      0
5 FALSE FALSE FALSE    NA    NA    NA    NA FALSE FALSE     NA     0     0     0     0     0     0     0     0     0      0
6    NA    NA    NA FALSE FALSE  TRUE FALSE FALSE FALSE  FALSE     0     0     0     0     0     1     1     1     1      1

РЕДАКТИРОВАТЬ: Просто прочитайте последние строки вашего сообщения.Если вы хотите сохранить NA в новых столбцах, просто поставьте df2[is.na(df)] <- NA перед cbind.Мне немного непонятно, что именно вы хотите, поэтому, если это не то, что вы ищете, можете ли вы опубликовать фрейм данных с желаемым выводом для данных образца?Прокомментируйте или опубликуйте обновление, если у вас возникнут другие проблемы!

EDIT2: еще один способ выполнить шаг, включающий apply (который может быть медленным).Я не мог проверить, какой путь был быстрее, поэтому я хотел включить оба:

# Changing all values after TRUE to 1
df2[] <- lapply(df2, as.numeric)
df2_t <- data.frame(t(df2))
> data.frame(t(cumsum(df2_t) > 0)*1)
   r_1RS r_2RS r_3RS r_4RS r_5RS r_6RS r_7RS r_8RS r_9RS r_10RS
X1     0     0     0     0     0     0     0     1     1      1
X2     0     0     0     0     1     1     1     1     1      1
X3     0     0     0     0     0     0     0     0     0      1
X4     0     0     0     0     0     0     0     0     0      0
X5     0     0     0     0     0     0     0     0     0      0
X6     0     0     0     0     0     1     1     1     1      1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...