代码之家  ›  专栏  ›  技术社区  ›  Nowak

r dpylr从线性模型中提取估计值,并将其用于变量调整突变-用于多个列

  •  1
  • Nowak  · 技术社区  · 6 年前

    问题

    我正在进行一项研究,利用食物日记中的数据。我需要根据总能量摄入调整营养素。我将根据以下描述的营养残留模型进行调整: Willet et al. 1997 . 为了计算这个残差,我需要通过一些步骤来改变营养柱,这些步骤涉及从线性模型中提取估计值。如果可能的话,我想用dplyr来做这个,但我不知道该怎么做。


    例子

    以下是我的数据框架示例:

    df <- data.frame(
      energy = c(3582, 3703, 3810, 3909, 4047, 4311, 4476, 4714, 5000, 5053, 5113, 5350, 5585, 5757, 6235, 6625, 6692, 6827, 6884, 7047, 7174, 7311, 7573, 7968, 10797, 11070),
      protein = c(43.55, 45.2, 48.1, 49.1, 54.6, 56.4, 61.15, 65.55, 70, 70.7, 71.55, 71.65, 74.15, 77.55, 79.2, 80.6, 81.6, 83.15, 83.2, 85.85, 91.85, 92.5, 98.4, 101.65, 105.6, 146.3),
      fat = c(20.9, 21.95, 25.7, 25.95, 34.95, 37.3, 38.2, 39.45, 40.8, 44.55, 44.95, 45.1, 48, 48.4, 52.3, 59.6, 62.15, 63.7, 64.1, 64.45, 67.5, 67.55, 70.95, 73.7, 88.6, 111.2))
    

    从一个以蛋白质为因变量、能量为自变量的线性回归模型中,我提取了截距和斜率:

    lm(protein ~ energy, data=df) #intercept = 10.56574 slope = 0.01095 
    

    我需要使用这些估计来突变营养变量(蛋白质),以获得调整后的营养变量(调整后的蛋白质):

    df <- df %>% 
      mutate(protein_residual = protein - (10.56574+0.01095 *energy),
             expected_protein_from_mean_kj = (10.56574+0.01095*mean(energy)),
             adjusted_protein = protein_residual+expected_protein_from_mean_kj)
    

    或者简化,因为我需要直接调整营养素:

    df <- df %>% 
      mutate(protein = (protein - (10.56574+0.01095 *energy)) + (10.56574+0.01095*mean(energy)))
    

    目标

    由于我有不止一个营养变量需要根据能量摄入进行调整,所以我想一次在多个列上运行简化的突变。我试图定义一个自定义函数,并将其放入调用mutate_at中,但收到了一条错误消息:

    residual <- function(data, nutrient, energy){
        (nutrient - (lm(nutrient ~ energy, data=data)$coefficient[1] + lm(nutrient ~ energy, data=data)$coefficient[2] * energy)) + 
        (lm(nutrient ~ energy, data=data)$coefficient[1] + lm(nutrient ~ energy, data=data)$coefficient[2] * mean(energy)) 
    }
    
    df <- df %>% 
      mutate_at(vars(protein,fat), funs(residual(.,energy)))
    
    # Error in mutate_impl(.data, dots) : 
      Evaluation error: numeric 'envir' arg not of length one.
    

    有没有更好的方法来解决这个问题?

    1 回复  |  直到 6 年前
        1
  •  2
  •   andrew_reece    6 年前

    residual() data lm() x y

    residual(nutrient, energy)

    residual <- function(nutrient, energy){
        mod <- lm(nutrient ~ energy)
        (nutrient - (mod$coefficient[1] + mod$coefficient[2] * energy)) + 
        (mod$coefficient[1] + mod$coefficient[2] * mean(energy)) 
    }
    

    df %>% mutate_at(vars(protein, fat), funs(residual(., energy)))
       energy  protein      fat
    1    3582 70.27792 46.73896
    2    3703 70.60333 46.50843
    3    3810 72.33200 49.12606
    4    3909 72.24825 48.32835
    5    4047 76.23757 55.86791
    ...