R语言 如何在按因子分组的循环中运行函数?

lawou6xi  于 2023-03-05  发布在  其他
关注(0)|答案(2)|浏览(176)

我尝试在 Dataframe df中循环函数f,并将输出存储在result中。该函数对v中的值进行采样,并将其存储在v. sample中。但是,我希望该函数仅进行循环,从而对v进行采样,同时将m保持在同一物种sp

set.seed(100)
x <- c(1,1,1,1,1,1,2,3,4,5,11,11,11,11,11,500,782,234,124,566)
v <- c(1,1,1,1,1,1,2,3,4,5,11,11,11,11,11,60,80,123,44,55)
sp <- rep(c("A", "B", "C", "D"), each=5)

df <- data.frame(x, v, sp)
df$sp <- as.factor(df$sp)

library(data.table)
setDT(df)

f <- function(x, v) {
  v.sample <- sample(v, length(v), replace=TRUE)
  y.sample <- (v.sample/x^2) - (1/x)
  per <- cor(y.sample, x, use="complete.obs")
  # storing all vectors in a dataframe
  data.frame( v.sample = v.sample, y.sample = y.sample, rand.cor = per)
}

result <- rbindlist(
  lapply(1:9, \(i)  df[, .(f(x, v),x,v, sp)][, i:=i])
)

目前,v.sample在所有物种之间移动,例如,在我设置虚拟数据集的方式中,sp == A的v.sample必须仅为1;而sp == D必须在44 and 123之间变化,目前,它在所有物种sp之间移动

pnwntuvh

pnwntuvh1#

我们可以对数据进行split,然后在每个sp上运行UDF,并将结果 Package 为rbindlist。也许有一种方法使用组by,但我想不出来。

rbindlist(
          lapply(split(df, df$sp), function(dat)
              rbindlist(
                        lapply(1:9, function(i) dat[, .(f(x, v), x, v, sp)][, i:=i])
                        )
          )
)
#>      v.sample      y.sample  rand.cor   X   V SP i
#>   1:        1  0.000000e+00        NA   1   1  A 1
#>   2:        1  0.000000e+00        NA   1   1  A 1
#>   3:        1  0.000000e+00        NA   1   1  A 1
#>   4:        1  0.000000e+00        NA   1   1  A 1
#>   5:        1  0.000000e+00        NA   1   1  A 1
#>  ---                                              
#> 176:       44 -1.824000e-03 -0.311902 500  60  D 9
#> 177:       80 -1.147952e-03 -0.311902 782  80  D 9
#> 178:      123 -2.027175e-03 -0.311902 234 123  D 9
#> 179:      123 -6.503642e-05 -0.311902 124  44  D 9
#> 180:       55 -1.595100e-03 -0.311902 566  55  D 9
46scxncf

46scxncf2#

如果你对使用dplyr的解决方案感兴趣,那么我认为这就是你所概述的:

library(dplyr)
f <- function(.data,...){
  .data %>%
    mutate(v_sample = sample(x = v,size = n(),replace = TRUE),
           y_sample = (v_sample / x^2) - (1/x),
           rand_cor = cor(y_sample,x,use = 'complete.obs'))
}

rep_f <- function(.data,n = 9,...){
  replicate(n = n,expr = f(.data),simplify = FALSE)
}

df %>%
  group_by(sp) %>%
  group_map(.f = ~rep_f(.x,n = 9)) %>%
  bind_rows()

请注意,按照您设置数据的方式,cor()会由于常量数据而抛出大量警告,因此您得到的sd为零。

相关问题