#r #dplyr
#r #dplyr
Вопрос:
Сохраняйте строки (Obs), значение Obs которых превышает пороговое значение выборки, ПО КРАЙНЕЙ МЕРЕ, В ТРЕХ ВЫБОРКАХ. Удалите строки, содержащие 2 или менее.
т.е..
- Obs 1 имеет только S5 выше порогового значения, поэтому будет отфильтрован;
- Obs2 имеет 4, а Obs 3 имеет 3, поэтому они останутся в df.
.
df <- data.frame(column=c("threshold", "Obs1", "Obs2", "Obs3"), S1 = c(1.7,1.4,1.9,1.3), S2= c(0.9,0.8,2,1), S3=c(2.5,2.4,2.1,0.5), S4=c(0.4,0.5,0.6,0.9), S5=c(1.2,1.4,1.3,1.6))
df
column S1 S2 S3 S4 S5
threshold 1.7 0.9 2.5 0.4 1.2
Obs1 1.4 0.8 2.4 0.5 1.4
Obs2 1.9 2.0 2.1 0.6 1.3
Obs3 1.3 1.0 0.5 0.9 1.6
Желаемый результат:
column S1 S2 S3 S4 S5
Obs2 1.9 2.0 2.1 0.6 1.3
Obs3 1.3 1.0 0.5 0.9 1.6
Я не знаю, как это закодировать, но мне интересно, использует ли какая-то логика, подобная этой:
logic <- if df (S1-5)>= threshold value then =1; if df (S1-5) < threhold then = 0
library(dplyr)
logic %>% rowwise %%
filter(sum(c_across(where(is.numeric))) >= 3) %>%
ungroup
Комментарии:
1. Первая строка df, называемая «пороговым значением», включает пороговое значение для каждого столбца
Ответ №1:
Если мы используем rowwise
with c_across
, только slice
строки без строки «порог», а затем выполните сравнение >
с соответствующим slice
общим набором данных с «пороговыми» строками
library(dplyr)
df %>%
slice(-1) %>%
rowwise %>%
filter(sum(c_across(where(is.numeric))
>
(df %>%
slice(1) %>%
select(-1))) >=3) %>%
ungroup
-вывод
# A tibble: 2 x 6
# column S1 S2 S3 S4 S5
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 Obs2 1.9 2 2.1 0.6 1.3
#2 Obs3 1.3 1 0.5 0.9 1.6
Если есть и другие символьные столбцы, мы можем изменить select
данные для подмножества
df %>%
slice(-1) %>%
rowwise %>%
filter(sum(c_across(where(is.numeric)) > df %>%
slice(1) %>%
select(where(is.numeric))) >=3)
Или другой вариант с map
library(purrr)
library(magrittr)
i1 <- map(df %>%
select(where(is.numeric)), ~ .x[-1] > first(.x)) %>%
reduce(` `) %>%
is_greater_than(2)
df %>%
slice(-1) %>%
filter(i1)
Или base R
с помощью rowSums
df[-1,][rowSums(df[-1, -1] > df[1, -1][col(df[-1, -1])]) >=3,]
# column S1 S2 S3 S4 S5
#3 Obs2 1.9 2 2.1 0.6 1.3
#4 Obs3 1.3 1 0.5 0.9 1.6
Комментарии:
1. Спасибо, все они работают, но я бы тоже хотел их понять. Для опции (1- dplyr) какая функция устанавливает значение «больше, чем значение»?; для опции (2-map ) означает ли значение is_greater_than(2 ) больше значения в строке 2? для (3-base) где вы говорите «дайте значение 1, если оно больше порогового значения?. Извините за много вопросов, но я хотел бы учиться! Спасибо @akrun
2. @Ecg Для варианта 1 мы сначала устанавливаем подмножества строк, потому что это по строкам. Таким образом, строка с пороговыми данными строки передается непосредственно внутрь, чтобы выполнить соответствующее
>
сc_across
помощью, т.е. (df %>% slice(1) %>% select(-1))
и пороговое значение выполняется>=3
. Во втором случае мы перебираем числовые столбцы сmap
помощью подмножества первого элемента и проводим сравнение с остальными, создаем индекс (‘i1’) и используем его для подмножества строк.3. Отлично, спасибо, внимательно прочитайте и постарайтесь понять. !
4. Я нахожу, что код с моими данными не работает, потому что мои «пороговые значения» являются десятичными, тогда как другие значения — нет. ТАКИМ образом, код не будет работать с чем-то вроде этого: < df1 <- data.frame(column=c(«threshold», «Obs1», «Obs2», «Obs3»), S1 = c(1.7,1,2,2), S2= c(1.3,0,0,3), S3=c(0.5,1,1,2), S4=c(1.2,1,2,2), S5=c(1.6,3,1,2)) > могу ли я отменить тот факт, что пороговые значения являются десятичными?
5. @Ecg Не ясно, когда вы говорите, что он не работает. Я попробовал ваш пример, и он работает для меня
Ответ №2:
Для дальнейшего использования: если вы работаете со столбцами, которые являются символьными, вам необходимо убедиться, что столбцы со значениями являются числовыми, если нет, преобразуйте их
df <- type.convert(df, as.is = TRUE)
и тогда это должно сработать
df2 <- df %>% slice(-1) %>% rowwise %>% filter(sum(c_across(where(is.numeric)) > (df %>%slice(1))) >=3)