R循环:每3行执行一次功能

时间:2019-07-05 21:33:43

标签: r loops dataframe data-manipulation

我有2000株小麦,生长40天。 我想在每个植物上执行coeff函数,以找到3个时间点构成的二次方程的系数。 (a,b和c)

(1)coef(lm(y~poly(x,2,raw=TRUE))函数的工作方式与我想要的完全相同。

(2)但是,显示数据的方式要求我手动设置x和y。

(3)因此,我融化了数据,并对其进行了排序。

(4)我想创建一个循环,该循环将采用“天”列中的前三个并将其设置为x。然后,我希望它采用“高度”列中的前三个并将其设置为y。

然后我想执行coeff功能。

最后,我希望它提供我需要的系数输出,最好在新的数据表中显示。

然后对于所有小麦植物,每三行重复一次,代表每一个小麦ID。

1)此函数有效,给我系数:a,b,c

x<-c(1,2,3)
y<-c(1,10,4)
coef(lm(y~poly(x,2,raw=TRUE)))

2)这就是我的数据原来的样子

A = matrix(c(5, 4, 2, 10, 10, 4, 5, 15, 6),nrow=3, ncol=3)
colnames(A)<-c("10", "25", "40")
rownames(A)<-c("Wheat 1", "Wheat 2", "Wheat 3")
A

3)这是我融化的格式

A.melted<-as.data.frame(melt(A, id.vars="ID"))
A.melted<-A.melted[with(A.melted,order(Var1)),]
colnames(A.melted) <- c("WheatID", "Day", "Height")
A.melted$Day<-as.numeric(as.character(A.melted$Day))
A.melted

4)这就是我要处理的循环。...

  • 每3行
  • x<-A.melted[,2]
  • y<-A.melted[,3]
  • coef(lm(y~poly(x,2,raw=TRUE)))
  • 可以用来编译系数的东西:a,b,c

我只是不熟悉循环的语法,并且我喜欢任何提示和建议。细读Google告诉我,除非绝对需要这样做,否则不应该执行循环,因为这样可能会遇到更多问题,因此我也对非循环技术持开放态度。

4 个答案:

答案 0 :(得分:0)

我们可以在data.table的帮助下完成此操作,请参见?data.table

library(data.table)

A.models = A.melted[, model := list(.(lm(Height ~ poly(Day, 2), 
                                         data = list(.(.SD[WheatID == .BY[[1]]]))))), 
                    by = WheatID] 

A.models[, coefs := list(.(coefficients(model[[1]]))), 
         by = WheatID]

您可以按以下方式访问每个模型:

A.models[WheatID == "Wheat 1", model[[1]]]

甚至

A.models[WheatID == "Wheat 1", summary(model[[1]])]

之所以发生这种魔术,是因为data.table接受了J 表达式,而不仅仅是功能。

答案 1 :(得分:0)

如果要循环执行,请尝试此操作。至关重要的部分是将seqby =参数一起使用,以使索引采取所需的步骤。

library(tibble)

df <- tibble(
  WheatID = rep(NA_character_, nrow(A)),
  Intercept = rep(NA_real_, nrow(A)),
  poly1 = rep(NA_real_, nrow(A)),
  poly2 = rep(NA_real_, nrow(A))
)
cnt <- 1
for (i in seq(1, nrow(A.melted), by = 3)) {
  x <- A.melted$Day[i + 0:2]
  y <- A.melted$Height[i + 0:2]
  df$WheatID[cnt] <- as.character(A.melted$WheatID[i])
  df[cnt, 2:4] <- coef(lm(y~poly(x,2,raw=TRUE)))
  cnt <- cnt + 1
}
df

注意:我不是data.table人。因此,我向您介绍tibble

答案 2 :(得分:0)

这是您可以使用data.table软件包执行的操作。

data.list <- split(A.melted, f = (1:nrow(A.melted) - 1) %/% 3)
coefs <- lapply(data.list, function(x) {
  coefs <- coef(lm(Day ~ poly(Height, raw=TRUE), data = x))
  data.table(
    intercept = coefs[1],
    poly.height = coefs[2]
  )
})

coefs <- rbindlist(coefs)

答案 3 :(得分:0)

或者您可以直接在原始矩阵上执行apply()

x <- as.numeric(colnames(A))
apply(A, 1, function(y) coef(lm(y~poly(x,2,raw=TRUE))))

                            Wheat 1      Wheat 2       Wheat 3
(Intercept)             -3.88888889 -0.555555556  6.666667e-01
poly(x, 2, raw = TRUE)1  1.11111111  0.477777778  1.333333e-01
poly(x, 2, raw = TRUE)2 -0.02222222 -0.002222222 -2.417315e-18

或者您可以转置数据并直接使用coef(...)调用:

x <- as.numeric(colnames(A))
coef(lm(t(A) ~ poly(x, 2, raw = TRUE)))