【问题标题】:Making a loop for lme() in r在 r 中为 lme() 创建一个循环
【发布时间】:2016-04-27 12:14:22
【问题描述】:

我正在尝试在 for 循环中使用 nlme 包中的 lme 函数。我现在(几乎)尝试了一切,但没有任何运气。没有循环,我的 lme 函数工作正常。我有 681 种不同的脂质要分析,所以我需要循环。

奖金信息:

  • 我使用了 str() 并且我的数据在循环之前具有相同的长度

我的数据的简化版本如下所示:

>dput(head("ex.lme(loop)")) structure(list(Lacal.Patient.ID = c(12L, 12L, 12L, 13L, 13L, 13L), Time = c(0L, 1L, 3L, 0L, 1L, 3L), Remission = c(0L, 0L, 1L, 0L, 0L, 1L), Age = c(46L, 43L, 36L, 47L, 34L, 45L), SEX = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("f", "m"), class = "factor"), BMI = c(25L, 26L, 23L, 27L, 26L, 27L), Sph = c(0.412, 1.713, 1.48, 0.735, 1.025, 1.275), S1P = c(2.412, 3.713, 3.48, 2.735, 3.025, 3.275), Cer..C16. = c(1.4472, 2.2278, 2.088, 1.641, 1.815, 1.965)), .Names = c("Lacal.Patient.ID", "Time", "Remission", "Age", "SEX", "BMI", "Sph", "S1P", "Cer..C16."), row.names = c(NA, 6L ), class = "data.frame")

这是我的工作 R:

library(nlme) attach(cer_data) Remission <- factor(Remission) Time <- factor(Time) SEX <- factor(SEX)

我认为循环应该是这样的:

lipid <-as.matrix(cer_data[,c(7:9)]) # my lipids a at row 7-9in my data 
beg <- 1
end <- nrow(lipid)
dim(lipid)
for (i in beg:end) { 
  print(paste("Running entity: ", colnames(lipid)[i], " which is ",i, " out of", end))
  variable <- as.numeric(lipid[i])
  lme_cer <- lme(variable ~ Remission + Time + Age + BMI + SEX, random = ~1|Lacal.Patient.ID, method = "REML", data = cer_data)
}

错误:model.frame.default 中的错误(公式 = ~variable + Remission + Time + :可变长度不同(为“Remission”找到)

没有循环,我的分析工作正常(Lipid(x) 只是其中一种脂质):

lme_cer <- lme(lipid(x) ~ Remission + Time + Age + BMI + SEX , random = ~1 | Lacal.Patient.ID, method = "REML", data = cer_data)
summary(lme_cer)

谁能看到我的循环的问题?我不习惯编程或使用 R,所以可能有一些愚蠢的错误。

【问题讨论】:

  • 现在你为每一行做 lme 是错误的。看end &lt;- nrow(lipid)。您应该选择独特的脂质并为它们进行循环。
  • dput 用于使问题可重现的数据
  • 您应该重新评估数据集的行和列中的内容。四个观察:首先,在创建lipid 数据时,您从完整数据集中选择了一些列。其次,出于某种原因,您随后会写“我的脂质在第 1-881 行”,这肯定是不正确的。第三,您创建了一个从1nrow(lipids) 的循环运行,即使您的变量在列中(而不是在行中)。最后,在循环中,您选择lipid[i],它既不选择行也不选择列,而只选择该矩阵的单个元素。
  • 如果您有解决方案,能否将其发布为答案而不是编辑您的问题??
  • nlme 有一些用于拟合许多模型的内置函数,这些函数可以代替 for 循环工作。见?lmList

标签: r loops nlme


【解决方案1】:

一个盲目的答案,假设您的因变量是按列而不是按行组织的(我认为它们是)。

我的方法和您的方法之间的主要区别在于,我循环遍历脂质的名称,而不是它们在数据集中的位置。这允许我 (a) 以不易出错的方式构建临时数据集,以及 (b) 为模型的固定效应部分构建临时公式。

lme 函数随后通过临时公式应用于临时数据集,并将结果保存在列表中以便于访问。

# names of lipids
lipid.names <- colnames(cer_data)[1:881]
no.lipids <- length(lipid.names)

# create a named list to hold the fitted models
fitlist <- as.list(1:no.lipids)
names(fitlist) <- lipid.names

# loop over lipid names
for(i in lipid.names){ 

  # print status
  print(paste("Running entity:", i, "which is", which(lipid.names==i), "out of", no.lipids))

  # create temporary data matrix and model formula
  tmp <- cer_data[, c(i,"Remission","Time","Age","BMI","SEX","Local.Patient.ID")]
  fml <- as.formula( paste( i, "~", paste(c("Remission","Time","Age","BMI","SEX"), collapse="+") ) )

  # assign fit to list by name
  fitlist[[i]] <- lme(fml, random=~1|Lacal.Patient.ID, method="REML", data=tmp)

}

在我看来,使用完全包含循环迭代所需内容的临时对象是最简单的。

请注意,我无法检查此解决方案是否有错误,因为您没有提供可重现的示例:Here's how

【讨论】:

    【解决方案2】:

    解决方案:我的循环现在正在使用这个简单的代码:

    lipid <-as.data.frame(cer_data[,c(7:9)]) dim(lipid) for (i in 1:length(lipid)) { variable <- lipid[,i] lme_cer <- lme(variable ~ factor(Remission) + Time + Age + BMI + SEX, random = ~1 | Lacal.Patient.ID, method = "REML", data = cer_data) print(summary(lme_cer)$tTable) }

    感谢大家的帮助!

    【讨论】:

      【解决方案3】:

      在不知道你的数据的情况下,从概念上来说应该是这样的

      df <- data.frame(lipid = rep(c(LETTERS[1:4]), each = 4), x1 = c(rnorm(16, 10, 1)), x2 = c(rnorm(16, 20, 5) ))
          df
      
      for (i in levels(df$lipid)){
        print(paste("MODEL", i, sep = ""))
        df1 = subset(df, lipid == i)
        model <- lm(x1~x2, data = df1 )
        print(summary(model)$coef)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-10-29
        • 1970-01-01
        • 2019-05-03
        • 2016-05-16
        • 1970-01-01
        • 2021-09-14
        • 2022-01-22
        相关资源
        最近更新 更多