Вопрос по r, dataframe – r индекс базы данных со значениями условия по вектору

2

Кажется, это довольно легко, но с тех пор я занят.

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

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

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

Я не хочу подмножество данных.

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

Ваш Ответ

3   ответа
5

Приведенный пример данных и порогов

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

Update: Поскольку @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
@mitchbu Поднявшись на вызов DWin, я обновил свой ответ в свете комментария об использовании двух порогов.
Большое спасибо!! Я вижу, mapply делает именно то, что я хочу! mitchbu
Спасибо большое за ваше обновление, это делает работу именно так, как мне нужно. Вы также помогли мне приблизительно понять концепцию mapply, ваш пост очень дидактичен. mitchbu
ХОРОШО. Это работает довольно хорошо. Здесь все немного сложнее (по крайней мере, мне): вместо одного вектора с порогами у меня есть два вектора. Один для верхнего порога, один для нижнего порога. Остальные данные должны находиться между двумя порогами. mitchbu
@mitchbu В этом случае сделайтеmapply() однажды с">" и снова с"<" поставляя один порог кmapply() вызов. Это даст вам две логические матрицы, которые вы можете комбинировать с&: sqy у вас верхний порог логический вupr и нижний порог логический вlwr тогда вы могли бы сделатьdat[lwr & upr], Если это недостаточно ясно, опубликуйте новый вопрос Q, чтобы объяснить проблему, и воспроизводимый пример, и мы можем взглянуть.
0

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

Спасибо за вашу помощь тоже. mitchbu
2

Мне нравится ответ Гевина лучше, чем мой, но здесь немного другое применение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)
Большое спасибо за ваше решение тоже. Я добавлю это как комментарий в мой код для будущего использования. Однако в настоящее время мне больше нравится версия Гевина, потому что я, кажется, лучше узнаю, как работает mapply. Тем не менее, я люблю однострочники. mitchbu

Похожие вопросы