Вернуть строки, в которых последовательные значения соответствуют критерию - PullRequest
0 голосов
/ 10 января 2019

У меня есть следующий фрейм данных df. Я хотел бы вернуть вектор result, который указывает, какие строки соответствуют следующему критерию: как минимум 2 последовательных значения в этой строке ниже -1,7.

set.seed(123)

df <- data.frame(V1=rnorm(10,-1.5,.5),
                 V2=rnorm(10,-1.5,.5),
                 V3=rnorm(10,-1.5,.5),
                 V4=rnorm(10,-1.5,.5),
                 V5=rnorm(10,-1.5,.5),
                 V6=rnorm(10,-1.5,.5),
                 V7=rnorm(10,-1.5,.5),
                 V8=rnorm(10,-1.5,.5),
                 V9=rnorm(10,-1.5,.5),
                 V10=rnorm(10,-1.5,.5))
rownames(df) <- c(seq(1976,1985,1))

Результатом будет вектор:

result <- c(1977,1979,1980,1982,1983,1985)

Ответы [ 3 ]

0 голосов
/ 10 января 2019

Интересный вариант с использованием which с arr.ind = TRUE

temp <- which(df < -1.7, arr.ind = TRUE)
rownames(df)[aggregate(col~row, temp, function(x) any(diff(x) == 1))[, 2]]

#[1] "1977" "1979" "1980" "1982" "1983" "1985"

Сначала мы получаем все позиции строк и столбцов, где значение меньше -1,7. Используя aggregate, мы группируем col для каждого row и проверяем, есть ли хотя бы одно последовательное значение в строке, и для значений, которые возвращают TRUE, поднабор его rownames.

0 голосов
/ 10 января 2019

Решение, которое использует лаговую сумму , чтобы получить сумму каждой пары чисел в векторе. Если отстающая сумма получает 2, то это означает, что как минимум 2 последовательных значения в этой строке удовлетворяют условию.

rownames(df)[apply(df < -1.7, 1, function(x) any(x[-nrow(df)] + x[-1] == 2))]

# [1] "1977" "1979" "1980" "1982" "1983" "1985"
0 голосов
/ 10 января 2019

Один из вариантов - циклически проходить по строкам с помощью apply, создавать логическое условие с помощью rle, проверять, существуют ли any ИСТИННЫЕ элементы, которые имеют lengths больше 1, извлекать names

names(which(apply(df, 1, function(x) with(rle(x < - 1.7), any(lengths[values] > 1)))))
#[1] "1977" "1979" "1980" "1982" "1983" "1985"

Или лучший подход - это векторизовать его, поместив две логические матрицы (т.е. удалить первый столбец набора данных, проверить, меньше ли он -1,7, аналогично удалить последний столбец и сделать то же самое), Reduce it к одному логическому matrix, проверив, являются ли соответствующие элементы TRUE, получите rowSums, если значение больше 0, мы извлекаем имена строк

names(which(rowSums(Reduce(`&`, list(df[-ncol(df)] < -1.7, df[-1] < -1.7))) > 0))
#[1] "1977" "1979" "1980" "1982" "1983" "1985"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...