首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数据帧上的行式while循环?

数据帧上的行式while循环?
EN

Stack Overflow用户
提问于 2020-08-28 17:13:09
回答 2查看 73关注 0票数 0

我有一个函数根据输入变量计算一些东西,但我想根据函数的结果更改输入变量。我觉得这是一个非常微不足道的问题,但我还没有找到一个可行的解决方案。

我有一个类似下面的数据集:

代码语言:javascript
复制
v1<-sample(5:12, 10, replace=T)
v2<-rep(100, 10)
v3<-rep(1,10)
v4<-sample(1:4, 10, replace=T)
t1<-sample(10:30, 10, replace=T)

和一个函数,它使用变量v1到v4来计算一些东西:

代码语言:javascript
复制
fun<-function(v1, v2, v3, v4){
  #does complicated things
  result<-((v2/(v1*v4))*v3
  return(result)
}

out<-fun(v1, v2, v3, v4)
df<-data.frame(v1, v2, v3, v4, t1, out)

我需要t1 < out。对于非矢量化的数据,这似乎是可行的:

代码语言:javascript
复制
while (out < t1){
  v3= v3 + 1
  out<- fun(v1, v2, v3, v4)
}

理想情况下,v3的最后一个值是以某种方式存储的。

代码语言:javascript
复制
v1  v1  v2 v3 v4 t1 out out_new v3_new
1   6 100  1  2 15  8.333333 16 2
2  12 100  1  2 17  4.166667 20 5
3   5 100  1  1 12 20.000000 20 1
4  10 100  1  4 26  2.500000 . . 
5   8 100  1  2 15  6.250000 . .
6   6 100  1  3 18  5.555556 
7  10 100  1  4 20  2.500000 
8  11 100  1  2 12  4.545455 
9  12 100  1  3 28  2.777778
10  6 100  1  2 25  8.333333

我正在寻找的输出是一个数据帧,看起来像这样:我正在寻找的是一个在大型(100.000行)数据帧/tibble上工作的矢量化解决方案。我用dplyr尝试了不同的方法(用case_when变异),但没有找到一个可行的解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-08-28 17:20:59

有一种方法可以使用dplyr::rowwise()实现这一点

代码语言:javascript
复制
library(tidyverse)
v1<-sample(5:12, 10, replace=T)
v2<-rep(100, 10)
v3<-rep(1,10)
v4<-sample(1:4, 10, replace=T)
t1<-sample(10:30, 10, replace=T)

fun<-function(v1, v2, v3, v4){
  #does complicated things
  result<-(v1/v2)*v4*v3
  return(result)
}

reallyWeirdFunction = function(v1, v2, v3, v4, t){
  out<- fun(v1, v2, v3, v4)
  while (out < t){
    v3= v3 + 1
    out<- fun(v1, v2, v3, v4)
  }
  out
}

df<-data.frame(v1, v2, v3, v4, t1)
df %>% 
  rowwise() %>% 
  mutate(
    out=fun(v1, v2, v3, v4), 
    out2=reallyWeirdFunction(v1, v2, v3, v4, t1)
  )
#> # A tibble: 10 x 7
#> # Rowwise: 
#>       v1    v2    v3    v4    t1   out  out2
#>    <int> <dbl> <dbl> <int> <int> <dbl> <dbl>
#>  1     7   100     1     3    17  0.21  17.0
#>  2    11   100     1     2    24  0.22  24.2
#>  3    12   100     1     1    11  0.12  11.0
#>  4    10   100     1     4    15  0.4   15.2
#>  5    10   100     1     2    22  0.2   22  
#>  6     9   100     1     1    16  0.09  16.0
#>  7     5   100     1     2    24  0.1   24  
#>  8    12   100     1     2    23  0.24  23.0
#>  9     8   100     1     3    30  0.24  30  
#> 10     7   100     1     2    14  0.14  14.

Created on 2020-08-28 by the reprex package (v0.3.0)

然而,在R中使用while循环通常是一个非常糟糕的主意,并且rowwise()在大型数据集中可能非常慢。您绝对应该尝试找到一种更好的算法,而不是像现在这样递增v3。不过,我找不到适合你的例子。

票数 1
EN

Stack Overflow用户

发布于 2020-08-28 17:46:47

使用mapply()和其他一些定义,您可以在base R中执行以下操作:

代码语言:javascript
复制
set.seed(42)
df <- data.frame(v1=sample(5:12, 10, replace=T), v2=rep(100, 10), v3=rep(1,10), 
                 v4=sample(1:4, 10, replace=T), t1=sample(10:30, 10, replace=T))

fun<-function(v1, v2, v3, v4) {
  #does complicated things
  result <- ((v2/(v1*v4))*v3)
  return(result)
}

fun2 <- function(v1, v2, v3, v4, t) {
  out <- fun(v1, v2, v3, v4)
  while (out < t){
    v3 <- v3 + 1
    out <- fun(v1, v2, v3, v4)
  }
  return(list(v3new=v3, out=out))
}

cbind(df, t(mapply(fun2, df$v1, df$v2, df$v3, df$v4, df$t1)))
> cbind(df, t(mapply(fun2, df$v1, df$v2, df$v3, df$v4, df$t1)))
#    v1  v2 v3 v4 t1 v3new      out
# 1   5 100  1  3 24     4 26.66667
# 2   9 100  1  4 12     5 13.88889
# 3   5 100  1  3 18     3       20
# 4   5 100  1  4 13     3       15
# 5   6 100  1  1 14     1 16.66667
# 6   8 100  1  1 22     2       25
# 7   6 100  1  2 14     2 16.66667
# 8   6 100  1  4 29     7 29.16667
# 9   5 100  1  2 11     2       20
# 10 12 100  1  2 17     5 20.83333
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63630844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档