如何计算不同列中每一行的斜率和截距

How to calculate slope and intercept for every row in different columns

我正在尝试计算数据框中不同列中每一行的斜率和截距。输出(截距和斜率)应作为新列添加到原始数据框中。

为了尽可能清楚地说明我要实现的目标,我在下面提供了一些数据:

locations<-c("a","b","c")

proportion.I<-c(0.073846154, 0.079710145, 0.063218391)

proportion.II<-c(0.049773659, 0.033756955, 0.011237956)

proportion.III<-c(0.090322581, 0.100917431, 0.08051443)

abundance.I<-c(331,331,331)

abundance.II<-c(178,178,178)

abundance.III<-c(87,87,87)

output.slope<-c(5.539e-05, -4.665e-05, -2.819e-05)

output.intercept<-c(5.128e-02, 8.073e-02, 5.726e-02)

df<-data.frame(locations, proportion.I, proportion.II, proportion.III, abundance.I, abundance.II, abundance.III, output.slope, output.intercept)

*我的线性回归的 'dependent' 变量将是 'Proportion'(行 2:4),预测变量(或自变量)将是 'abundance'(行 5:7).

好吧,您的数据不是“整齐”的格式,这使得使用大多数内置函数变得困难。您可以使用 dplyrtidyr 将您的数据转换为一个共享,以便更轻松地进行分组回归。例如

library(dplyr)
library(tidyr)

df %>% 
  select(-starts_with("output")) %>%                   #drop "answers"
  pivot_longer(proportion.I:abundance.III) %>%         # convert to long format
  separate(name, into = c("var", "idx")) %>%           # get values from column names
  pivot_wider(names_from=var, values_from=value) %>%   # go back to wide
  nest(data=-locations) %>%                             
  mutate(reg = map(data, ~lm(abundance~proportion, .))) %>%   # do the regression
  mutate(intercept=map_dbl(reg, ~coefficients(.)[1]),         # get values form regression
         slope=map_dbl(reg, ~coefficients(.)[2]))

这与您提供的值相匹配,但从您的描述来看,您似乎希望以另一种方式进行回归:~lm(proportion~abundance, .)

我们可以使用 base Rfor 循环中执行此操作。创建一个 NULL listlength 等于数据集 ('out') 的行数来存储输出。获取数据集中 'proportion'、'abundance' 列的名称 ('prp'、'abn')。遍历数据集的行序列,提取'prp'、'abn'列,用lm创建模型,提取系数,赋给list元素'out'。最后,rbind list 元素并将其分配给原始数据集中的新列

out <- vector('list', nrow(df))
prp <- names(df)[startsWith(names(df), "proportion")]
abn <- names(df)[startsWith(names(df), "abundance")]
for(i in seq_len(nrow(df)))  out[[i]] <- coef(lm(abundance ~ proportion,
   data.frame(abundance = unlist(df[i, abn]), proportion = unlist(df[i, prp]))))

df[c('slope', 'intercept')] <- do.call(rbind, out)[,2:1]
df[, c("slope", "intercept")]
#       slope intercept
#1 -1613.9597  313.7648
#2  -601.7193  241.6664
#3  -329.6502  215.6954