#r #dplyr #tidyverse
Вопрос:
Прежде всего, я не смог найти вопрос, связанный с моей проблемой, приношу извинения, если на этот вопрос уже был дан ответ.
У меня есть фрейм данных с некоторыми столбцами, и я хочу вычислить новое значение, используя определенную формулу. Я предполагаю, что мне придется использовать mutate()
из tidyverse, но я хочу избежать строк/выборок, в которых есть одно или несколько значений 0. Я не знаю, как я могу проверить, есть ли какой-либо 0, когда я использую mutate()
. Кроме того, я не знаю, как я могу применить свою конкретную формулу для создания нового столбца.
Я оставляю здесь код для создания фрейма данных в качестве примера моей проблемы.
set.seed(123)
df <- data.frame(
time = seq(now(), now() hours(11),by='hours'),
a = sample(0:100,12),
b = sample(0:100,12),
c = sample((0:20)/1000,12))
df[1:3,]$a <- 0
df[3:5,]$b <- 0
df[3:4,]$c <- 0
# function: M = a*b (1-e^(-c/2))
# if any 0 in the row -> M = NA
# else: apply function
Функция может быть записана как
a*b*(1-exp(-c/2))
В окончательном df должно быть 4 столбца за каждый час (строка) (a,b,c и новое вычисленное M), но когда a | b | c == 0, M = NA
.
Я буду очень благодарен за каждую небольшую помощь. Ура!
РЕДАКТИРОВАТЬ: Реальная функция сложнее, чем в этом примере,поэтому не всегда будет верно,что если один член (a, b, c,…) равен 0, то результирующее M равно 0. Извините, я не понял, что этот постулат верен для упрощенного уравнения. Но я хочу избежать любого значения 0, потому что они получены из мониторинга физиологических переменных, и я знаю, что если одно значение равно 0 в выборке, то выборка неверна, так что НЕТ.
Ответ №1:
Если какое-либо из a
, b
или c
равно 0, оно возвращается M
как 0, которое можно изменить на NA
.
library(dplyr)
df %>%
mutate(M = a*b*(1-exp(-c/2)),
M = na_if(M, 0))
# time a b c M
#1 2021-10-18 19:41:56 0 90 0.013 NA
#2 2021-10-18 20:41:56 0 56 0.016 NA
#3 2021-10-18 21:41:56 0 0 0.000 NA
#4 2021-10-18 22:41:56 13 0 0.000 NA
#5 2021-10-18 23:41:56 66 0 0.011 NA
#6 2021-10-19 00:41:56 41 71 0.014 20.305847
#7 2021-10-19 01:41:56 49 25 0.009 5.500115
#8 2021-10-19 02:41:56 42 6 0.012 1.507473
#9 2021-10-19 03:41:56 97 41 0.017 33.661237
#10 2021-10-19 04:41:56 24 97 0.008 9.293401
#11 2021-10-19 05:41:56 89 82 0.019 69.002718
#12 2021-10-19 06:41:56 68 35 0.015 17.783230
Комментарии:
1. О, извините, возможно, это был не лучший пример, я попытался упростить набор данных и уравнение. Уравнение упрощено. Например,в оригинале есть добавленный термин, поэтому неверно, что если один термин равен 0, M будет равен 0. Я опубликую исходное уравнение здесь: a b*(c d(1-exp(-e/(f g)))) Я использую буквы, чтобы было легче понять. Извините за недоразумение. Знаете ли вы, можно ли использовать условие, как я просил изначально, без использования этого «математического» трюка, который вы опубликовали?
2. Если есть способ использовать что-то вроде части » M = na_if(M, 0)», но вместо M искать 0 в a, b, c,…, этого будет достаточно, но я не знаю ни одной подобной функции. Ty
3. В конце концов, я использовал ваш подход, но наоборот. Во-первых, я заменил все 0 значениями NA, поэтому уравнение вернет NA. Я отмечу ваш ответ как решение. Однако я все равно был бы признателен, если бы знал, есть ли способ сделать это с учетом условий.
4. @RobertoT Как насчет
df %>% mutate(M = ifelse(if_any(a:c, ~. == 0), NA, a*b*(1-exp(-c/2))))
?5. Большое спасибо! Я не знал, все ли. Это отличное решение.