R 计算列中的值作为同一行位置上上一列值的函数

R 计算列中的值作为同一行位置上上一列值的函数,r,function,dataframe,R,Function,Dataframe,我有很多列,我想根据函数(1+x)^k计算它们的值,其中x是特定列的值,k是我们试图计算的列的索引。我只想计算表中所有列的子集 对于axample: df=data.frame(A=c(0.1,0.05,0.2),B=c(1,1,1),c=c(NA,NA,NA),D=c(NA,NA,NA) 我只想使用A列中的值将函数应用于C列和D列 例如,df[1,4]将被计算为(1+(-0.1)^4,因为4是D列的索引 另一种解释是,对于所选列(本例中的C和D),该值是前一列的值乘以(1+x),即df[1,4

我有很多列,我想根据函数(1+x)^k计算它们的值,其中x是特定列的值,k是我们试图计算的列的索引。我只想计算表中所有列的子集

对于axample:

df=data.frame(A=c(0.1,0.05,0.2),B=c(1,1,1),c=c(NA,NA,NA),D=c(NA,NA,NA)

我只想使用A列中的值将函数应用于C列和D列

例如,df[1,4]将被计算为(1+(-0.1)^4,因为4是D列的索引


另一种解释是,对于所选列(本例中的C和D),该值是前一列的值乘以(1+x),即df[1,4]=df[1,3]*(1+(-0.1)),给出相同的结果

一个
dplyr
选项可以是:

df %>%
 rowwise() %>%
 mutate((1 + A)^(across(C:D, ~ replace(., is.na(.), 1)) * which(names(.) %in% c("C", "D"))))

      A     B     C     D
  <dbl> <dbl> <dbl> <dbl>
1  0.1      1  1.33  1.46
2  0.05     1  1.16  1.22
3  0.2      1  1.73  2.07

也许是这样的:

f = function(df, target_cols = c("C", "D"), index_col = "A"){
  
  # df is your data frame 
  # target_cols is a vector of columns you want apply the function (1 + x)^k 
  # index_col is the the x in (1 + x)^k

  stopifnot(all(target_cols %in% names(df)))
  stopifnot(index_col %in% names(df))
  
  # Get index of target columns i.e k
  which_col = which(names(df) %in% target_cols)
  
  # Loop over columns
  for(i in which_col){
    df[, i] = (1 + df[, index_col])^i
  }
  
  return(df)
  
}

df = data.frame(A = c(0.1, 0.05, 0.2), B = c(1, 1, 1), C = c(NA, NA, NA), D = c(NA, NA, NA))
f(df)                

     A B        C        D
1 0.10 1 1.331000 1.464100
2 0.05 1 1.157625 1.215506
3 0.20 1 1.728000 2.073600

您描述的功能定义如下:

func1 = function(df, i) {
  (1+df[1]^i)
}

base R
中的一个选项是

df[3:4] <- (1 + df$A)^col(df)[, 3:4]

或者使用
映射/累积

library(purrr)
library(dplyr)
map_dfc(set_names(match(c('C', 'D'), names(df)), names(df)[3:4]), ~ {
            i <- .x
            accumulate(df$A,  ~(1 + .y)^i, 
              .init = first(df$A))[-1]}) %>% 
   bind_cols(df[1:2], .)
#     A B        C        D
#1 0.10 1 1.331000 1.464100
#2 0.05 1 1.157625 1.215506
#3 0.20 1 1.728000 2.073600
库(purrr)
图书馆(dplyr)
地图(集合名称)(匹配(c('c','D'),名称(df)),名称(df)[3:4]),~{
i%
绑定列(df[1:2],)
#A、B、C、D
#1 0.10 1 1.331000 1.464100
#2 0.05 1 1.157625 1.215506
#3 0.20 1 1.728000 2.073600

谢谢!这证明了对于极其复杂的问题通常有简单的解决方案。
df[c('C', 'D')] <- lapply(match(c('C', 'D'), names(df)), function(i) 
     Reduce(function(x, y) (1 + y)^i, df[, 'A'],
          accumulate = TRUE, init = df$A[1])[-1])

df
#     A B        C        D
#1 0.10 1 1.331000 1.464100
#2 0.05 1 1.157625 1.215506
#3 0.20 1 1.728000 2.073600
library(purrr)
library(dplyr)
map_dfc(set_names(match(c('C', 'D'), names(df)), names(df)[3:4]), ~ {
            i <- .x
            accumulate(df$A,  ~(1 + .y)^i, 
              .init = first(df$A))[-1]}) %>% 
   bind_cols(df[1:2], .)
#     A B        C        D
#1 0.10 1 1.331000 1.464100
#2 0.05 1 1.157625 1.215506
#3 0.20 1 1.728000 2.073600