【问题标题】:Using coefficients (slope and intercept) from one data frame to calculate a list of values from a second data frame使用来自一个数据帧的系数(斜率和截距)来计算来自第二个数据帧的值列表
【发布时间】:2020-05-04 07:50:37
【问题描述】:

我有几个物种的长度列表(n=30),我们称它们为 A1、A2、A3、A4、A5:

A1<-(sample(x = 0:100, size  = 30, replace=TRUE))
A2<-(sample(x = 0:100, size  = 30, replace=TRUE))
A3<-(sample(x = 0:100, size  = 30, replace=TRUE))
A4<-(sample(x = 0:100, size  = 30, replace=TRUE))
A5<-(sample(x = 0:100, size  = 30, replace=TRUE))

df<-data.frame(A1,A2,A3,A4,A5)

对于每个物种的这些长度,我想使用特定物种的斜率和截距 (y=mx+b) 来计算重量:

sample <- c("A1", "A2", "A3", "A4", "A5")
intercept <- rnorm(5, mean = 10, sd = 1)
slope <- rnorm(5, mean = 10, sd = 1)
upper <- rnorm(5, mean = 10, sd = 1) + rnorm(5, mean = 0.01, sd = 1)
lower <- rnorm(5, mean = 10, sd = 1) + rnorm(5, mean = 0.01, sd = 1)

coef<-data.frame(sample, intercept, slope, upper, lower)

其中上限和下限是 95% 的置信区间。

我的问题是,对于每个物种(即每个长度值)列 (df) 的每一行,我如何根据 coef 数据框中的物种特定 y = 斜率 * x + 截距值计算重量?

我尝试为每个物种创建额外的列(例如 A1.intercept、A1.slope、A1.upper、A1.lower),然后跨行重复(coef)中的相同值,但 1)我可以' t 让代码正常工作 2)我有很多物种(A1 - A70),所以代码很长。

我已经尝试了各种 grep 选项,但我还是空白。非常感谢任何帮助!

【问题讨论】:

    标签: r arrays dataframe dplyr


    【解决方案1】:

    在基数 R 中,您可以首先创建截距矩阵,在该矩阵中重复观察次数的截距:

    b = t(replicate(nrow(df),coef$slope[match(colnames(df),coef$sample)]))
    

    然后,将每一行乘以匹配的斜率:

    mx = sweep(df,2,coef$slope[match(colnames(df),coef$sample)],"*")
    

    你需要的是:

    y = mx+b
    

    你也可以使用 dplyr 进行合并(我想还不错,因为你没有很多):

    library(dplyr)
    library(tidyr)
    df %>% tibble::rownames_to_column("id")  %>% 
    pivot_longer(-id,names_to="sample") %>% 
    left_join(coef)  %>% 
    mutate(y=intercept+value*slope)
    

    【讨论】:

    • 基础 R 解决方案非常优雅 - 谢谢!但不应该是mx = sweep(df,2,coef$slope[match(colnames(df),coef$sample)],"*") 而不是mx = sweep(df,2,coef$slope[match(colnames(df),coef$sample)],"/") 吗?
    • 哦是的..对不起..我使用“/”太频繁了。感谢您发现我的错误
    【解决方案2】:
    library(dplyr)
    set.seed(1) # reproducible data set
    A1<-(sample(x = 0:100, size  = 30, replace=TRUE))
    A2<-(sample(x = 0:100, size  = 30, replace=TRUE))
    A3<-(sample(x = 0:100, size  = 30, replace=TRUE))
    A4<-(sample(x = 0:100, size  = 30, replace=TRUE))
    A5<-(sample(x = 0:100, size  = 30, replace=TRUE))
    
    df<-data.frame(A1,A2,A3,A4,A5)
    
    sample <- c("A1", "A2", "A3", "A4", "A5")
    intercept <- rnorm(5, mean = 10, sd = 1)
    slope <- rnorm(5, mean = 10, sd = 1)
    upper <- rnorm(5, mean = 10, sd = 1) + rnorm(5, mean = 0.01, sd = 1)
    lower <- rnorm(5, mean = 10, sd = 1) + rnorm(5, mean = 0.01, sd = 1)
    
    coef <- data.frame(sample, intercept, slope, upper, lower)
    
    If I have understood your question this may help you
    df %>% 
    tidyr::gather(sample,x) %>% # get df in long format
    left_join(.,coef,"sample") %>% # join data
    mutate(y = slope * x + intercept) # apply equation
    

    【讨论】:

      猜你喜欢
      • 2020-10-12
      • 1970-01-01
      • 1970-01-01
      • 2018-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-09
      相关资源
      最近更新 更多