в R измените столбец dataframe с первого появления второго столбца - PullRequest
0 голосов
/ 28 июня 2018

У меня есть датафрейм, похожий на этот:

set.seed(1004)
x <- c(sort(rnorm(40)),sort(rnorm(20)),
       sort(rnorm(40)),sort(rnorm(20)))
x[30:40] <- -x[30:40]+1
x[90:100] <- -x[90:100]+1

y <- c(rep('a',times = 60),rep('b',times = 60))
z <- 1:length(x)

df <- data.frame(z, x, y)

Я хотел бы создать новый столбец в соответствии с x и y. Я хочу, чтобы в каждой подгруппе y (то есть 'a' и 'b' в примере), первый случай, когда x > 0, следующие строки для этого дополнительного столбца должны иметь одинаковое значение (коэффициент). И это, хотя x < 0 снова после этого первого происшествия.

В конце я хочу что-то вроде:

df$y2 <- c(rep('0', times = 20), rep('1', times = 40), rep('0', times = 19), rep('1', times = 41))

Пока я пробовал это:

library(magrittr)
df %<>% 
  mutate(y2 = case_when(
    x < 0 ~ '0',
    x >= 0 ~ '1'
  ))

Но мне не хватает аргумента, так что y2 остается на «1», хотя x снова становится отрицательным.

Графическое представление того, что я хочу: пока у меня есть это:

enter image description here

Пока я хочу это:

enter image description here

Ответы [ 2 ]

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

Здесь я использую функцию Position, чтобы найти позицию первого вхождения, которая удовлетворяет определенным критериям. В этом случае х> 0. Затем я создаю вектор со значениями для нового столбца на основе этой позиции.

library(dplyr)
library(magrittr)

createNewValues <- function(x){
  splitPoint <- Position(function(x) x>0, x)
  return(rep(c(0, 1), times = c(splitPoint-1, length(x)-splitPoint+1)))
}

df %<>% 
  group_by(y) %>% 
  mutate(y2 = createNewValues(x))
0 голосов
/ 28 июня 2018
df <- data.frame(z, x, y)
df$y2 <- c(rep('0', times = 20), rep('1', times = 40), rep('0', times = 19), rep('1', times = 41))

library(magrittr)
df %<>% 
  group_by(y) %>% 
  mutate(y3 = cummax(ifelse(x < 0, 0, 1))) #by taking cummax, y3 will always be 1 after the first x > 0 for each group y

table(df$y2 == df$y3, useNA = "always")

TRUE <NA> 
 120    0 
...