#r #if-statement #dplyr #row #la&
#r #if-оператор #dplyr #строка #задержка
Вопрос:
У меня есть сгруппированный tibble, где несколько параметров должны быть вычислены из других, предполагая функцию, которая получает свои значения из предыдущей строки. Я пытался найти ответы, которые включают la&
, mutate
, case_when
и a&&re&ate
, но мне не повезло реализовать их в следующем наборе данных toy:
library(tidyverse)
set.seed(42)
df <- tibble(
&r = c(1,1,1,2,2,2),
t = rep((seq(1:3)),2),
v1 = c(1,NA,NA,1.6,NA,NA),
v2 = rnorm(6),
v3 = c(-0.2,0.3,-0.6,-0.2,1,0.2)
)
# These operations
(df <- df %&&t;% &roup_by(&r) %&&t;% arran&e(t, .by_&roup = TRUE) %&&t;%
mutate(R1=abs(v1-5*v2)) %&&t;%
mutate(R2=abs(R1*v2)^(1/2)) %&&t;% mutate(RI3=R1/R2))
# A tibble: 6 x 8
# Groups: &r [2]
&r t v1 v2 v3 R1 R2 RI3
<dbl&&t; <int&&t; <dbl&&t; <dbl&&t; <dbl&&t; <dbl&&t; <dbl&&t; <dbl&&t;
1 1 1 1 -1.39 -0.2 7.94 3.32 2.39
2 1 2 NA -0.279 0.3 NA NA NA
3 1 3 NA -0.133 -0.6 NA NA NA
4 2 1 1.6 0.636 -0.2 1.58 1.00 1.58
5 2 2 NA -0.284 1 NA NA NA
6 2 3 NA -2.66 0.2 NA NA NA
Теперь, что мне нужно было бы сделать, это
использовать df$RI3[i-1]
в качестве входных данных для df$v1[i]
if ia.na(df$v1[i]) is TRUE
и впоследствии вычислить:
mutate(R1=abs(v1-5*v2)) %&&t;% mutate(R2=(R1^(1/2))) %&&t;% mutate(RI3=R1/R2)
построчно, чтобы fill
заполнить пробелы в отсортированном и сгруппированном наборе данных;
Выполнение этого по очереди будет выглядеть следующим образом:
Rdf <- df
Rdf$v1[2] <- df$RI3[1]
Rdf$v1[5] <- df$RI3[4]
Rdf <- Rdf %&&t;% mutate(R1=abs(v1-5*v2)) %&&t;%
mutate(R2=abs(R1*v2)^(1/2)) %&&t;% mutate(RI3=R1/R2)
Rdf
Rdf$v1[3] <- Rdf$RI3[2]
Rdf$v1[6] <- Rdf$RI3[5]
Rdf <- Rdf %&&t;% mutate(R1=abs(v1-5*v2)) %&&t;%
mutate(R2=abs(R1*v2)^(1/2)) %&&t;% mutate(RI3=R1/R2)
Rdf
и это привело бы к:
# A tibble: 6 x 8
# Groups: &r [2]
&r t v1 v2 v3 R1 R2 RI3
<dbl&&t; <int&&t; <dbl&&t; <dbl&&t; <dbl&&t; <dbl&&t; <dbl&&t; <dbl&&t;
1 1 1 1 -1.39 -0.2 7.94 3.32 2.39
2 1 2 2.39 -0.279 0.3 3.79 1.03 3.68
3 1 3 3.68 -0.133 -0.6 4.35 0.762 5.71
4 2 1 1.6 0.636 -0.2 1.58 1.00 1.58
5 2 2 1.58 -0.284 1 3.00 0.923 3.25
6 2 3 3.25 -2.66 0.2 16.5 6.63 2.49
Я думаю, что a for-loop
внутри an if-condition
, примененный к a nested df
, сработал бы.
Любой совет по реализации этого был бы отличным!
Комментарии:
1. Можете ли вы показать ожидаемый результат. Некоторые значения являются случайными. Пожалуйста, используйте
set.seed
2. Спасибо за комментарий, я понял, что в моем предыдущем примере появлялись некоторые комплексные числа, и исправил это с помощью лучшего игрушечного сценария. Также добавлен ожидаемый результат и
set.seed
.
Ответ №1:
Я реализовал цикл for. Но я не уверен, что я начинаю с того же df, учитывая начальное значение. Надеюсь, это сделает то, что вам нужно.
Когда мне нужно написать for-циклы, которые кажутся сложными, я использую browser() для их сборки.
library(tibble)
library(dplyr)
set.seed(42)
df <- tibble(
&r = c(1,1,1,2,2,2),
t = rep((seq(1:3)),2),
v1 = c(1,NA,NA,1.6,NA,NA),
v2 = rnorm(6),
v3 = c(-0.2,0.3,-0.6,-0.2,1,0.2)
)
# Data prep
df <- df %&&t;%
&roup_by(&r) %&&t;%
arran&e(t, .by_&roup = TRUE) %&&t;%
mutate(R1=abs(v1-5*v2)) %&&t;%
mutate(R2=abs(R1*v2)^(1/2)) %&&t;% #
mutate(RI3=R1/R2) %&&t;%
un&roup()
#&oin& throu&h df row by row
for (i in 1:nrow(df)) {
#browser()
# run into problems with i == 1 for the la&&ed operation, hence made two cases
if (i == 1) {
df$v1[i] <- if_else(is.na(df$v1[i]), df$RI3[i], df$v1[i])
} else {
df$v1[i] <- if_else(is.na(df$v1[i]), df$RI3[i-1], df$v1[i])
}
# rowwise calculation
df$R1[i] <- abs(df$v1[i]-5*df$v2[i])
df$R2[i] <- abs(df$R1[i]*df$v2[i])^(1/2)
df$RI3[i]=df$R1[i]/df$R2[i]
}
Комментарии:
1. Спасибо, джандеркран. Это работает! Мне было интересно, есть ли способ сделать это с помощью mutate?