如何将数据帧列中的所有先前观测值按组迭代地除以最后一个观测值,然后将结果存储在R中
我有以下数据框:如何将数据帧列中的所有先前观测值按组迭代地除以最后一个观测值,然后将结果存储在R中,r,iteration,grouping,R,Iteration,Grouping,我有以下数据框: data <- data.frame("Group" = c(1,1,1,1,1,1,1,1,2,2,2,2), "Days" = c(1,2,3,4,5,6,7,8,1,2,3,4), "Num" = c(10,12,23,30,34,40,50,60,2,4,8,12)) 然后只保留值为2的行,因为我不关心其他行(我希望值大于或等于2,最接近2),并返回该值的日期,也就是4。然后,转到50并执行以下操作: Day Num Res 6 50/40 1.25 5 5
data <- data.frame("Group" = c(1,1,1,1,1,1,1,1,2,2,2,2),
"Days" = c(1,2,3,4,5,6,7,8,1,2,3,4), "Num" = c(10,12,23,30,34,40,50,60,2,4,8,12))
然后只保留值为2的行,因为我不关心其他行(我希望值大于或等于2,最接近2),并返回该值的日期,也就是4。然后,转到50并执行以下操作:
Day Num Res
6 50/40 1.25
5 50/34 1.47
4 50/30 1.67
3 50/23 2.17
2 50/12 4.17
1 50/10 5
然后只保留值为2.17的行,并返回该值的日期,也就是3。然后,继续到40,再做同样的事情,继续到34,然后30,然后23,然后12,最后一个值(或第1天的值),我不在乎。然后转到下一组的最后一个值(12),并对该组重复相同的方法(12/8,12/4,12/2;8/4,8/2;4/2)
我希望存储这些分区的结果,但仅存储大于或等于2的最新结果。我还想回到取得成果的那一天。基本上,我试图计算每天加倍的时间。我还需要按组对其进行分组。通常情况下,我会使用dplyr来实现这一点,但我不确定如何将一个循环与dyplr连接起来,以利用group_by。此外,我可能忽略了lapply或其一些变体。理想情况下,我预期的结果数据框如下:
data2 <- data.frame(divres = c(NA,NA,2.3,2.5,2.833333333,3.333333333,2.173913043,2,NA,2,2,3),
obs_n =c(NA,NA,1,2,2,2,3,4,NA,1,2,2))
data3 <- bind_cols(data, data2)
data2您可以修改division
函数来处理向量并返回一个包含两列divres
和ind
的数据帧。后者是用于计算obs\n
的行索引,如下所示:
division <- function(x){
lenx <- length(x)
y <- vector(mode="numeric", length = lenx)
z <- vector(mode="numeric", length = lenx)
for (i in lenx:1){
y[i] <- ifelse(length(which(x[i]/x[1:i]>=2))==0,NA,x[i]/x[1:i] [max(which(x[i]/x[1:i]>=2))])
z[i] <- ifelse(is.na(y[i]),NA,max(which(x[i]/x[1:i]>=2)))
}
df <- data.frame(divres = y, ind = z)
return(df)
}
使用cbind
将上述输出与数据帧data1
组合,使用pipes
和mutate
fromdplyr
使用ind
查找Day
中的obs\n
值,选择适当的列以生成所需的数据帧data2
:
您可以创建一个带有for循环的函数,以获得所需的日期,如下所示。然后用它来获得一个dplyr突变中的divres
obs_n <- function(x, days) {
lst <- list()
for(i in length(x):1){
obs <- days[which(rev(x[i]/x[(i-1):1]) >= 2)]
if(length(obs)==0)
lst[[i]] <- NA
else
lst[[i]] <- max(obs)
}
unlist(lst)
}
当你说“除以前面的所有值”时,这是否意味着在第一次迭代中,你从60
开始,然后(除以前面的所有值)执行60/50/40/34/30/23/12/10
(即1.065644e-08
)?这对我来说有点奇怪。。。我可能是在逐字逐句地阅读你的文章。我认为dplyr
足够简单,包括分组
,我建议你只讨论单个组的单个向量,比如c(10,12,23,30,34,40,50,60)
,并逐字解释你对该向量的预期结果,无论是内部还是外部,我现在就编辑这个问题,让它更清晰。哈哈,你说得对。我太累了…所以打个盹儿,但有趣的是,,,,@Maggie我想你的问题可能已经改变了。我很好奇这个解决方案是否正是你想要的。@Maggie你能澄清一下你是如何计算obs\n的吗?
?谢谢你写这篇文章,我会在我的大脑工作时再检查一遍,然后再给你回复。至于obs_n,这是2+结果发生的日子。因此,例如,当除以60时,在第4天获得2.0的值,因此理想情况下,循环将返回4作为obs_n的值。如果除以50,则第3天的结果为2.17,因此这将是返回给obs_n的值。我不知道这是否有意义。既然我写了这个,别告诉我你会怎么做。我想自己试试,如果我被难倒了,我会回来的!感谢您的评论,我确认这与我的数据相符。我将继续学习,以便能够完全理解循环的结构及其工作原理。谢谢您的回答。目前它对我不起作用,但我确信这是因为我将它错误地应用于我的实际数据。我将在本周末对此进行更多的研究,以了解问题所在。我发现您的实际数据可能与您提供的示例数据有所不同。
division <- function(x){
if(x>=2){
return(x)
} else {
return(FALSE)
}
}
for (i in 1:nrow(data)){
data$test[i]<- division(data$test[i])
}
division <- function(x){
lenx <- length(x)
y <- vector(mode="numeric", length = lenx)
z <- vector(mode="numeric", length = lenx)
for (i in lenx:1){
y[i] <- ifelse(length(which(x[i]/x[1:i]>=2))==0,NA,x[i]/x[1:i] [max(which(x[i]/x[1:i]>=2))])
z[i] <- ifelse(is.na(y[i]),NA,max(which(x[i]/x[1:i]>=2)))
}
df <- data.frame(divres = y, ind = z)
return(df)
}
> division(data$Num)
divres ind
1 NA NA
2 NA NA
3 2.300000 1
4 2.500000 2
5 2.833333 2
6 3.333333 2
7 2.173913 3
8 2.000000 4
9 NA NA
10 2.000000 9
11 2.000000 10
12 3.000000 10
data2 <- cbind.data.frame(data, division(data$Num)) %>% mutate(obs_n = Days[ind]) %>% select(-ind)
> data2
Group Days Num divres obs_n
1 1 1 10 NA NA
2 1 2 12 NA NA
3 1 3 23 2.300000 1
4 1 4 30 2.500000 2
5 1 5 34 2.833333 2
6 1 6 40 3.333333 2
7 1 7 50 2.173913 3
8 1 8 60 2.000000 4
9 2 1 2 NA NA
10 2 2 4 2.000000 1
11 2 3 8 2.000000 2
12 2 4 12 3.000000 2
obs_n <- function(x, days) {
lst <- list()
for(i in length(x):1){
obs <- days[which(rev(x[i]/x[(i-1):1]) >= 2)]
if(length(obs)==0)
lst[[i]] <- NA
else
lst[[i]] <- max(obs)
}
unlist(lst)
}
library(dplyr)
data %>%
group_by(Group) %>%
mutate(obs_n=obs_n(Num, Days), divres=Num/Num[dense_rank(obs_n)])
# A tibble: 12 x 5
# Groups: Group [2]
Group Days Num obs_n divres
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 10 NA NA
2 1 2 12 NA NA
3 1 3 23 1 2.3
4 1 4 30 2 2.5
5 1 5 34 2 2.83
6 1 6 40 2 3.33
7 1 7 50 3 2.17
8 1 8 60 4 2
9 2 1 2 NA NA
10 2 2 4 1 2
11 2 3 8 2 2
12 2 4 12 2 3
x <- c(NA, NA, 1,2,2,4,6)
dplyr::dense_rank(x)
# [1] NA, NA, 1 2 2 3 4
rank(x)
[1] 6.0 7.0 1.0 2.5 2.5 4.0 5.0