r нижний индекс кадра данных со значениями условия по вектору

это кажется довольно простым, но какое-то время это занимает меня.

У меня есть кадр данных (df) с n столбцами и вектором с таким же количеством (n) значений.

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

Я хочу сохранить все наблюдения в кадре данных, которые соответствуют различным пороговым значениям для каждого столбца (выше или ниже, в примере это не имеет значения). Наблюдения, которые не соответствуют пороговому критерию, должны быть установлены на 0.

Мне не нужно подмножество фрейма данных.

Кто-нибудь может помочь? Заранее большое спасибо.


person mitchbu    schedule 05.06.2012    source источник


Ответы (3)


Учитывая некоторые примеры данных и пороговые значения

set.seed(42)
dat <- data.frame(matrix(runif(100), ncol = 10))

## thresholds
thresh <- seq(0.5, 0.95, length.out = 10)
thresh

мы можем использовать функцию mapply(), чтобы определить, какие наблюдения в каждом столбце (в этом) больше или равны пороговому значению. Используя эти индексы, мы можем заменить значения, соответствующие индексам, на 0 через:

dat[mapply(">=", dat, thresh)] <- 0

Вот призыв в действии:

> dat
          X1        X2         X3          X4         X5
1  0.9148060 0.4577418 0.90403139 0.737595618 0.37955924
2  0.9370754 0.7191123 0.13871017 0.811055141 0.43577158
3  0.2861395 0.9346722 0.98889173 0.388108283 0.03743103
4  0.8304476 0.2554288 0.94666823 0.685169729 0.97353991
5  0.6417455 0.4622928 0.08243756 0.003948339 0.43175125
6  0.5190959 0.9400145 0.51421178 0.832916080 0.95757660
7  0.7365883 0.9782264 0.39020347 0.007334147 0.88775491
8  0.1346666 0.1174874 0.90573813 0.207658973 0.63997877
9  0.6569923 0.4749971 0.44696963 0.906601408 0.97096661
10 0.7050648 0.5603327 0.83600426 0.611778643 0.61883821
           X6        X7          X8         X9          X10
1  0.33342721 0.6756073 0.042988796 0.58160400 0.6674265147
2  0.34674825 0.9828172 0.140479094 0.15790521 0.0002388966
3  0.39848541 0.7595443 0.216385415 0.35902831 0.2085699569
4  0.78469278 0.5664884 0.479398564 0.64563188 0.9330341273
5  0.03893649 0.8496897 0.197410342 0.77582336 0.9256447486
6  0.74879539 0.1894739 0.719355838 0.56364684 0.7340943010
7  0.67727683 0.2712866 0.007884739 0.23370340 0.3330719834
8  0.17126433 0.8281585 0.375489965 0.08998052 0.5150633298
9  0.26108796 0.6932048 0.514407708 0.08561206 0.7439746463
10 0.51441293 0.2405447 0.001570554 0.30521837 0.6191592400
> dat[mapply(">=", dat, thresh)] <- 0
> dat
          X1        X2         X3          X4         X5
1  0.0000000 0.4577418 0.00000000 0.000000000 0.37955924
2  0.0000000 0.0000000 0.13871017 0.000000000 0.43577158
3  0.2861395 0.0000000 0.00000000 0.388108283 0.03743103
4  0.0000000 0.2554288 0.00000000 0.000000000 0.00000000
5  0.0000000 0.4622928 0.08243756 0.003948339 0.43175125
6  0.0000000 0.0000000 0.51421178 0.000000000 0.00000000
7  0.0000000 0.0000000 0.39020347 0.007334147 0.00000000
8  0.1346666 0.1174874 0.00000000 0.207658973 0.63997877
9  0.0000000 0.4749971 0.44696963 0.000000000 0.00000000
10 0.0000000 0.0000000 0.00000000 0.611778643 0.61883821
           X6        X7          X8         X9          X10
1  0.33342721 0.6756073 0.042988796 0.58160400 0.6674265147
2  0.34674825 0.0000000 0.140479094 0.15790521 0.0002388966
3  0.39848541 0.7595443 0.216385415 0.35902831 0.2085699569
4  0.00000000 0.5664884 0.479398564 0.64563188 0.9330341273
5  0.03893649 0.0000000 0.197410342 0.77582336 0.9256447486
6  0.74879539 0.1894739 0.719355838 0.56364684 0.7340943010
7  0.67727683 0.2712866 0.007884739 0.23370340 0.3330719834
8  0.17126433 0.0000000 0.375489965 0.08998052 0.5150633298
9  0.26108796 0.6932048 0.514407708 0.08561206 0.7439746463
10 0.51441293 0.2405447 0.001570554 0.30521837 0.6191592400

Поучительно заметить, что возвращает mapply() в этом случае:

> mapply(">=", dat, thresh)
         X1    X2    X3    X4    X5    X6    X7    X8    X9   X10
 [1,]  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
 [2,]  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
 [3,] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [4,]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
 [5,]  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [6,]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
 [7,]  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE
 [8,] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
 [9,]  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
[10,]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

и именно эти логические значения используются для выбора наблюдений, соответствующих порогу. Вы можете использовать бинарный оператор, отличный от того, который я использовал; см. ?">" для различных вариантов. При написании вызова mapply() думайте о нем с точки зрения левой и правой частей бинарного оператора, так что вызов mapply() даст:

mapply(">", lhs, rhs)

где мы могли бы написать

lhs > rhs

Обновление: поскольку @DWin ответил на комментарий о двух пороговых значениях, я обновлю свой ответ, чтобы он соответствовал.

thresh1 <- seq(0.05, 0.5, length.out = 10)
thresh2 <- seq(0.55, 0.95, length.out = 10)
set.seed(42)
dat <- data.frame(matrix(runif(100), ncol = 10))

l1 <- mapply(">", dat, thresh1)
l2 <- mapply("<", dat, thresh2)

Мы можем видеть, какие элементы соответствуют обоим ограничениям:

> l1 & l2
         X1    X2    X3    X4    X5    X6    X7    X8    X9   X10
 [1,] FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
 [2,] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
 [3,]  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE
 [4,] FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
 [5,] FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE  TRUE
 [6,]  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE
 [7,] FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE
 [8,]  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE
 [9,] FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE
[10,] FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE

и та же конструкция может использоваться для выбора тех элементов, которые соответствуют:

dat[l1 & l2] <- 0
dat

> dat
          X1        X2         X3          X4         X5         X6        X7          X8
1  0.9148060 0.0000000 0.90403139 0.737595618 0.00000000 0.00000000 0.0000000 0.042988796
2  0.9370754 0.7191123 0.13871017 0.811055141 0.00000000 0.00000000 0.9828172 0.140479094
3  0.0000000 0.9346722 0.98889173 0.000000000 0.03743103 0.00000000 0.0000000 0.216385415
4  0.8304476 0.0000000 0.94666823 0.685169729 0.97353991 0.78469278 0.0000000 0.000000000
5  0.6417455 0.0000000 0.08243756 0.003948339 0.00000000 0.03893649 0.8496897 0.197410342
6  0.0000000 0.9400145 0.00000000 0.832916080 0.95757660 0.00000000 0.1894739 0.000000000
7  0.7365883 0.9782264 0.00000000 0.007334147 0.88775491 0.00000000 0.2712866 0.007884739
8  0.0000000 0.0000000 0.90573813 0.000000000 0.00000000 0.17126433 0.8281585 0.375489965
9  0.6569923 0.0000000 0.00000000 0.906601408 0.97096661 0.26108796 0.0000000 0.000000000
10 0.7050648 0.0000000 0.83600426 0.000000000 0.00000000 0.00000000 0.2405447 0.001570554
           X9          X10
1  0.00000000 0.0000000000
2  0.15790521 0.0002388966
3  0.35902831 0.2085699569
4  0.00000000 0.0000000000
5  0.00000000 0.0000000000
6  0.00000000 0.0000000000
7  0.23370340 0.3330719834
8  0.08998052 0.0000000000
9  0.08561206 0.0000000000
10 0.30521837 0.0000000000
person Gavin Simpson    schedule 05.06.2012
comment
Спасибо большое!! Я вижу, что mapply делает именно то, что я хочу! - person mitchbu; 05.06.2012
comment
OK. Это работает очень хорошо. Здесь все немного сложнее (по крайней мере, для меня): вместо одного вектора с порогами у меня есть два вектора. Один для верхнего порога, другой для нижнего порога. Остальные данные должны находиться между двумя пороговыми значениями. - person mitchbu; 05.06.2012
comment
@mitchbu В этом случае выполните mapply() один раз с ">" и снова с "<", указав один порог для вызова mapply(). Это даст вам две логические матрицы, которые вы можете комбинировать с &: у вас есть верхний логический порог в upr и нижний логический порог в lwr, тогда вы можете сделать dat[lwr & upr]. Если это недостаточно ясно, опубликуйте новый вопрос, чтобы объяснить проблему и воспроизводимый пример, и мы сможем взглянуть. - person Gavin Simpson; 05.06.2012
comment
@mitchbu Принимая вызов DWin, я обновил свой ответ в свете комментария об использовании двух порогов. - person Gavin Simpson; 05.06.2012
comment
: большое спасибо за ваше обновление, это работает именно так, как мне нужно. Вы также помогли мне примерно понять концепцию mapply, ваш пост очень дидактичен. - person mitchbu; 06.06.2012

Ответ Гэвина мне нравится больше, чем мой, но вот немного другое применение mapply с использованием его данных:

mapply(function(x,tt) ifelse(x >= tt, 0, x), dat, thresh)

В свете вашего второго комментария: моя конструкция может быть более обобщенной, чем конструкция Гэвина.

Два пороговых вектора:

mapply(function(x, lt, ht) ifelse(x <= lt | x >= ht , 0, x), dat, lothresh, hithresh)
person IRTFM    schedule 05.06.2012
comment
большое спасибо за ваше решение, тоже. Я добавлю его в качестве комментария в свой код для будущего использования. Однако в настоящее время мне больше нравится версия Гэвина, потому что я, кажется, лучше узнаю, как работает mapply. Тем не менее, я люблю однострочные. - person mitchbu; 06.06.2012

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

person Havelock    schedule 05.06.2012