有没有办法沿着排序和分组的 tibble 进行条件和多行逐行操作?
Is there a way to do a conditional and multiple row by row operation along a sorted and grouped tibble?
我有一个分组的 tibble,其中几个参数必须根据其他参数计算,假设一个函数从前一行获取其值。我试图找到涉及 lag
、mutate
、case_when
和 aggregate
的答案,但没有在以下玩具数据集中实现这些答案:
library(tidyverse)
set.seed(42)
df <- tibble(
gr = 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 %>% group_by(gr) %>% arrange(t, .by_group = TRUE) %>%
mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% mutate(RI3=R1/R2))
# A tibble: 6 x 8
# Groups: gr [2]
gr t v1 v2 v3 R1 R2 RI3
<dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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)) %>% mutate(R2=(R1^(1/2))) %>% mutate(RI3=R1/R2)
逐行 fill
排序和分组数据集中的间隙;
一个一个地做这个看起来像这样:
Rdf <- df
Rdf$v1[2] <- df$RI3[1]
Rdf$v1[5] <- df$RI3[4]
Rdf <- Rdf %>% mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% mutate(RI3=R1/R2)
Rdf
Rdf$v1[3] <- Rdf$RI3[2]
Rdf$v1[6] <- Rdf$RI3[5]
Rdf <- Rdf %>% mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% mutate(RI3=R1/R2)
Rdf
并会导致:
# A tibble: 6 x 8
# Groups: gr [2]
gr t v1 v2 v3 R1 R2 RI3
<dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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
我想 if-condition
中的 for-loop
应用于 nested df
会起作用。
任何实施此建议的建议都很棒!
我实现了一个for循环。但是我不确定在给定种子的情况下我是否以相同的 df 开始。希望它能满足您的需求。
当我需要编写看起来很复杂的for-loops时,我使用browser()来构建它。
library(tibble)
library(dplyr)
set.seed(42)
df <- tibble(
gr = 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 %>%
group_by(gr) %>%
arrange(t, .by_group = TRUE) %>%
mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% #
mutate(RI3=R1/R2) %>%
ungroup()
#going through df row by row
for (i in 1:nrow(df)) {
#browser()
# run into problems with i == 1 for the lagged 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]
}
我有一个分组的 tibble,其中几个参数必须根据其他参数计算,假设一个函数从前一行获取其值。我试图找到涉及 lag
、mutate
、case_when
和 aggregate
的答案,但没有在以下玩具数据集中实现这些答案:
library(tidyverse)
set.seed(42)
df <- tibble(
gr = 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 %>% group_by(gr) %>% arrange(t, .by_group = TRUE) %>%
mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% mutate(RI3=R1/R2))
# A tibble: 6 x 8
# Groups: gr [2]
gr t v1 v2 v3 R1 R2 RI3
<dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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)) %>% mutate(R2=(R1^(1/2))) %>% mutate(RI3=R1/R2)
逐行 fill
排序和分组数据集中的间隙;
一个一个地做这个看起来像这样:
Rdf <- df
Rdf$v1[2] <- df$RI3[1]
Rdf$v1[5] <- df$RI3[4]
Rdf <- Rdf %>% mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% mutate(RI3=R1/R2)
Rdf
Rdf$v1[3] <- Rdf$RI3[2]
Rdf$v1[6] <- Rdf$RI3[5]
Rdf <- Rdf %>% mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% mutate(RI3=R1/R2)
Rdf
并会导致:
# A tibble: 6 x 8
# Groups: gr [2]
gr t v1 v2 v3 R1 R2 RI3
<dbl> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
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
我想 if-condition
中的 for-loop
应用于 nested df
会起作用。
任何实施此建议的建议都很棒!
我实现了一个for循环。但是我不确定在给定种子的情况下我是否以相同的 df 开始。希望它能满足您的需求。
当我需要编写看起来很复杂的for-loops时,我使用browser()来构建它。
library(tibble)
library(dplyr)
set.seed(42)
df <- tibble(
gr = 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 %>%
group_by(gr) %>%
arrange(t, .by_group = TRUE) %>%
mutate(R1=abs(v1-5*v2)) %>%
mutate(R2=abs(R1*v2)^(1/2)) %>% #
mutate(RI3=R1/R2) %>%
ungroup()
#going through df row by row
for (i in 1:nrow(df)) {
#browser()
# run into problems with i == 1 for the lagged 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]
}