函数依赖于R中的行中的值

函数依赖于R中的行中的值,r,function,dataframe,sapply,standard-deviation,R,Function,Dataframe,Sapply,Standard Deviation,我希望函数取决于数据框中每个产品的sd值。因此,不要在函数中输入常量sd值,因为每个产品都有不同的sd df <- data.frame(Product = c("A", "B"), Oct = c(33, 23), Nov = c(23, 26), SD = c(1, 5)) rand_vect_cont <- function(N, M, sd) { vec <-

我希望函数取决于数据框中每个产品的
sd
值。因此,不要在函数中输入常量
sd
值,因为每个产品都有不同的
sd

df <- data.frame(Product = c("A", "B"), 
                 Oct = c(33, 23),
                 Nov = c(23, 26),
                 SD = c(1, 5))

rand_vect_cont <- function(N, M, sd) {
  vec <- rnorm(N, M/N, sd)
  vec / sum(vec) * M
}

sapply(unlist(df[2:3]), rand_vect_cont, N = 4, df$SD)

我们可以使用
Map

do.call(cbind, Map(function(x, y) sapply(x, rand_vect_cont, N = 4, sd = y),
          asplit(as.matrix(df[2:3]), 1), df$SD))
 #     Oct      Nov       Oct       Nov
#[1,] 7.551047 5.053925  2.449044  3.174316
#[2,] 8.353440 5.853014  6.238516  6.992176
#[3,] 7.343861 4.847592  1.470566  2.188509
#[4,] 9.751653 7.245469 12.841873 13.644999

或使用
tidyverse

library(dplyr)
library(tidyr)
df %>%
   pivot_longer(cols = -c(Product, SD), names_to = "month") %>% 
   group_by(Product, month, SD) %>% 
   summarise(value = list(rand_vect_cont(4, value, SD)))  %>% 
   unnest(c(value))
# A tibble: 16 x 4
# Groups:   Product, month [4]
#   Product month    SD value
#   <fct>   <chr> <dbl> <dbl>
# 1 A       Nov       1  5.05
# 2 A       Nov       1  5.85
# 3 A       Nov       1  4.85
# 4 A       Nov       1  7.25
# 5 A       Oct       1  7.55
# 6 A       Oct       1  8.35
# 7 A       Oct       1  7.34
# 8 A       Oct       1  9.75
# 9 B       Nov       5  3.17
#10 B       Nov       5  6.99
#11 B       Nov       5  2.19
#12 B       Nov       5 13.6 
#13 B       Oct       5  2.45
#14 B       Oct       5  6.24
#15 B       Oct       5  1.47
#16 B       Oct       5 12.8 
库(dplyr)
图书馆(tidyr)
df%>%
pivot_longer(cols=-c(产品,SD),name_to=“month”)%>%
按产品、月份、标准差划分的组别%>%
总结(值=列表(随机向量控制(4,值,标准差))%>%
unnest(c(值))
#一个tibble:16 x 4
#分组:产品,月份[4]
#产品月SD值
#        
#1A 2005年11月15日
#1985年11月1日星期二
#3 A 1985年11月14日
#4a 11月17日25分
#5 A 10月17日55分
#10月18日上午6时35分
#10月17日上午7时34分
#2005年10月19日上午8点
#9 B 11月5日3.17
#1999年11月5日至6日10 B
#11B 11月5日2.19
#12 B 11月5日13.6
#13 B 10月5日2时45分
#14 B 10月5日6时24分
#15 B 10月5日1.47
#16 B 10月5日12月8日

编辑:使用@Sathish帖子中显示的相同种子

我们可以使用
Map

do.call(cbind, Map(function(x, y) sapply(x, rand_vect_cont, N = 4, sd = y),
          asplit(as.matrix(df[2:3]), 1), df$SD))
 #     Oct      Nov       Oct       Nov
#[1,] 7.551047 5.053925  2.449044  3.174316
#[2,] 8.353440 5.853014  6.238516  6.992176
#[3,] 7.343861 4.847592  1.470566  2.188509
#[4,] 9.751653 7.245469 12.841873 13.644999

或使用
tidyverse

library(dplyr)
library(tidyr)
df %>%
   pivot_longer(cols = -c(Product, SD), names_to = "month") %>% 
   group_by(Product, month, SD) %>% 
   summarise(value = list(rand_vect_cont(4, value, SD)))  %>% 
   unnest(c(value))
# A tibble: 16 x 4
# Groups:   Product, month [4]
#   Product month    SD value
#   <fct>   <chr> <dbl> <dbl>
# 1 A       Nov       1  5.05
# 2 A       Nov       1  5.85
# 3 A       Nov       1  4.85
# 4 A       Nov       1  7.25
# 5 A       Oct       1  7.55
# 6 A       Oct       1  8.35
# 7 A       Oct       1  7.34
# 8 A       Oct       1  9.75
# 9 B       Nov       5  3.17
#10 B       Nov       5  6.99
#11 B       Nov       5  2.19
#12 B       Nov       5 13.6 
#13 B       Oct       5  2.45
#14 B       Oct       5  6.24
#15 B       Oct       5  1.47
#16 B       Oct       5 12.8 
库(dplyr)
图书馆(tidyr)
df%>%
pivot_longer(cols=-c(产品,SD),name_to=“month”)%>%
按产品、月份、标准差划分的组别%>%
总结(值=列表(随机向量控制(4,值,标准差))%>%
unnest(c(值))
#一个tibble:16 x 4
#分组:产品,月份[4]
#产品月SD值
#        
#1A 2005年11月15日
#1985年11月1日星期二
#3 A 1985年11月14日
#4a 11月17日25分
#5 A 10月17日55分
#10月18日上午6时35分
#10月17日上午7时34分
#2005年10月19日上午8点
#9 B 11月5日3.17
#1999年11月5日至6日10 B
#11B 11月5日2.19
#12 B 11月5日13.6
#13 B 10月5日2时45分
#14 B 10月5日6时24分
#15 B 10月5日1.47
#16 B 10月5日12月8日
编辑:使用@Sathish的帖子中显示的相同种子将
set.seed()
放入函数中,以获得可复制的结果

df <- data.frame(Product = c("A", "B"), 
                 Oct = c(33, 23),
                 Nov = c(23, 26),
                 SD = c(1, 5))
rand_vect_cont <- function(N, M, sd) {
  set.seed(1); 
  vec <- rnorm(N, M/N, sd)
  vec / sum(vec) * M
}
set.seed()
放入函数中以获得可复制的结果

df <- data.frame(Product = c("A", "B"), 
                 Oct = c(33, 23),
                 Nov = c(23, 26),
                 SD = c(1, 5))
rand_vect_cont <- function(N, M, sd) {
  set.seed(1); 
  vec <- rnorm(N, M/N, sd)
  vec / sum(vec) * M
}


我需要unlist函数,因为我必须计算数据框中的每一个元素。@Elia是否对每个“产品”都这样做,即按行,在这种情况下,第二个选项应该可以工作,但它不能正常工作,我希望有四列,因为我必须将数据框中的每个元素分解为其总和。列中的总和与数据框中的值不匹配。@Elia,但您的帖子中没有该条件。我读到
希望函数依赖于数据框中每个产品的sd值。
我需要unlist函数,因为我必须计算数据框中的每个元素。@Elia您是否对每个“产品”都这样做,即按行,在这种情况下,第二个选项应该可以工作,但它不能正常工作,我希望有四列,因为我必须将数据框中的每个元素分解为其总和。列中的总和与数据框中的值不匹配。@Elia,但您的帖子中没有该条件。我读到
希望函数依赖于数据帧中每个产品的sd值。
当你
取消列表时,你将其视为单个向量。我的问题是,你不想对每个产品分别执行此操作
拆分(df[-1],df$product)
是的,它可以像那样分开吗你需要
sapply(取消列表(df[2:3]),矢量化(rand_vect_cont),N=4,sd=df$sd)
行太多,它应该是4,就像在我的示例中,当你
取消列表时,你把它看作是一个向量。我的问题是,你不想对每个产品分别进行
拆分(df[-1],df$Product)
是的,它可以像那样分开,你需要
吗(unlist(df[2:3]),Vectorize(rand_vect_cont),N=4,sd=df$sd)
行太多,应该是4,如我的示例所示