【问题标题】:creating a function for processing my dataframe calculations创建一个函数来处理我的数据框计算
【发布时间】:2014-11-12 05:47:33
【问题描述】:

我正在为我创建的数据框进行系统计算。我有计算代码,但我想:

1) 将其作为函数写入并为我创建的数据框调用它。

2) 重置数据框中下一个 ID 的计算。

感谢您对此提供的帮助和建议。

使用以下代码在 R 中创建数据框:

#Create a dataframe
dosetimes <- c(0,6,12,18)

df <- data.frame("ID"=1,"TIME"=sort(unique(c(seq(0,30,1),dosetimes))),"AMT"=0,"A1"=NA,"WT"=NA)
doserows <- subset(df, TIME%in%dosetimes)

doserows$AMT[doserows$TIME==dosetimes[1]] <- 100 
doserows$AMT[doserows$TIME==dosetimes[2]] <- 100
doserows$AMT[doserows$TIME==dosetimes[3]] <- 100
doserows$AMT[doserows$TIME==dosetimes[4]] <- 100

#Add back dose information
df <- rbind(df,doserows)
df <- df[order(df$TIME,-df$AMT),]       
df <- subset(df, (TIME==0 & AMT==0)==F)

df$A1[(df$TIME==0)] <- df$AMT[(df$TIME ==0)]


#Time-dependent covariate
df$WT <- 70                    
df$WT[df$TIME >= 12] <- 120  

#The calculations are done in a for-loop. Here is the code for it:
#values needed for the calculation
C <- 2     
V  <- 10    
k <- C/V

#I would like this part to be written as a function

for(i in 2:nrow(df))
{

t <- df$TIME[i]-df$TIME[i-1]
A1last <- df$A1[i-1]

df$A1[i] = df$AMT[i]+ A1last*exp(-t*k)
}

head(df)

plot(A1~TIME, data=df, type="b", col="blue", ylim=c(0,150))

另一件事是前面的代码假定所有时间点的主题 ID=1。如果当 WT(重量)更改为 120 时主题 ID=2。如何重置计算并使其对数据框中的所有主题 ID 自动执行?在这种情况下,原始数据框将是这样的:

#code:
rm(list=ls(all=TRUE))
dosetimes <- c(0,6,12,18)
df <- data.frame("ID"=1,"TIME"=sort(unique(c(seq(0,30,1),dosetimes))),"AMT"=0,"A1"=NA,"WT"=NA)
doserows <- subset(df, TIME%in%dosetimes)
doserows$AMT[doserows$TIME==dosetimes[1]] <- 100 
doserows$AMT[doserows$TIME==dosetimes[2]] <- 100
doserows$AMT[doserows$TIME==dosetimes[3]] <- 100
doserows$AMT[doserows$TIME==dosetimes[4]] <- 100
df <- rbind(df,doserows)
df <- df[order(df$TIME,-df$AMT),]       
df <- subset(df, (TIME==0 & AMT==0)==F)
df$A1[(df$TIME==0)] <- df$AMT[(df$TIME ==0)]
df$WT <- 70                    
df$WT[df$TIME >= 12] <- 120 
df$ID[(df$WT>=120)==T] <- 2
df$TIME[df$ID==2] <- c(seq(0,20,1))

提前谢谢你!

【问题讨论】:

  • 那么您实际上不知道其中的哪一部分?实际的编程问题在哪里?现在看来这只是一个“请为我做这件事”的请求。
  • 1.我想把for循环写成一个函数,这样我就可以为数据帧调用它;像 df2
  • 2:我不知道如何重置下一个主题 ID 的计算。 (即从 ID2 的 TIME=0 开始对 ID=2 再次进行相同的计算)@MrFlick

标签: r dataframe analysis


【解决方案1】:

一般来说,在对不同主题的数据进行计算时,我喜欢按 ID 拆分数据框,将单个主题数据的向量传递到 for 循环中,进行所有计算,构建一个包含所有新计算数据的向量,然后然后折叠结果并返回包含您想要的所有数字的数据框。这允许您对每个主题所做的事情进行大量控制

subjects = split(df, df$ID)
forResults = vector("list", length=length(subjects))

# initialize these constants
C <- 2     
V  <- 10    
k <- C/V

myFunc = function(data, resultsArray){
  for(k in seq_along(subjects)){
    df = subjects[[k]]
    df$A1 = 100 # I assume this should be 100 for t=0 for each subject?

    # you could vectorize this nested for loop..
    for(i in 2:nrow(df)) {

      t <- df$TIME[i]-df$TIME[i-1]
      A1last <- df$A1[i-1]

      df$A1[i] = df$AMT[i]+ A1last*exp(-t*k)
    }

    head(df)

    # you can add all sorts of other calculations you want to do on each subject's data

    # when you're done doing calculations, put the resultant into 
    # the resultsArray and we'll rebuild the dataframe with all the new variables
    resultsArray[[k]] = df

    # if you're not using RStudio, then you want to use dev.new() to instantiate a new plot canvas
    # dev.new()   # dont need this if you're using RStudio (which doesnt allow multiple plots open)
    plot(A1~TIME, data=df, type="b", col="blue", ylim=c(0,150))

  }

  # collapse the results vector into a dataframe
  resultsDF = do.call(rbind, resultsArray)
  return(resultsDF)
}

results = myFunc(subjects, forResults)

【讨论】:

  • 谢谢@skotturi。我测试了它,它实际上是在做错误的计算。看来我的问题我的问题还不够清楚。我再次发布了一个新问题,更清楚地说明了我想要实现的目标。如果您能看一下,我将不胜感激。 (stackoverflow.com/questions/25908142/…)
  • 看起来您收到了适合您的答案。我应该指出,该问题的答案与此答案的作用相同,它按主题拆分数据,运行您想要的所有计算(您似乎添加了几个变量),然后将整个数据框重新组合在一起.有一个名为 plyr 的精美软件包,尽管人们在学习 RI 时通常建议手动将其全部写出来,因为这样更容易看到发生了什么(而不是执行 unsplit(lappply(split(data,func))) . 它们都有效,只是取决于什么能帮助你最好地学习。
  • 感谢您的帮助和指导。你是绝对正确的;手动编写代码并理解它有很大帮助。老实说,我总是很难理解(应用)家庭功能。我每天都在学习更多 =)
【解决方案2】:

你想要这个吗:

ddf <- data.frame("ID"=1,"TIME"=sort(unique(c(seq(0,30,1),dosetimes))),"AMT"=0,"A1"=NA,"WT"=NA)

myfn = function(df){

    dosetimes <- c(0,6,12,18)
    doserows <- subset(df, TIME%in%dosetimes)

    doserows$AMT[doserows$TIME==dosetimes[1]] <- 100 
    doserows$AMT[doserows$TIME==dosetimes[2]] <- 100
    doserows$AMT[doserows$TIME==dosetimes[3]] <- 100
    doserows$AMT[doserows$TIME==dosetimes[4]] <- 100

    #Add back dose information
    df <- rbind(df,doserows)
    df <- df[order(df$TIME,-df$AMT),]       
    df <- subset(df, (TIME==0 & AMT==0)==F)

    df$A1[(df$TIME==0)] <- df$AMT[(df$TIME ==0)]


    #Time-dependent covariate
    df$WT <- 70                    
    df$WT[df$TIME >= 12] <- 120  

    #The calculations are done in a for-loop. Here is the code for it:
    #values needed for the calculation
    C <- 2     
    V  <- 10    
    k <- C/V

    #I would like this part to be written as a function

    for(i in 2:nrow(df))
    {

    t <- df$TIME[i]-df$TIME[i-1]
    A1last <- df$A1[i-1]

    df$A1[i] = df$AMT[i]+ A1last*exp(-t*k)
    }

    head(df)

    plot(A1~TIME, data=df, type="b", col="blue", ylim=c(0,150))

}

myfn(ddf)

对于多个调用:

for(i in 1:N) {
    myfn(ddf[ddf$ID==i,])
    readline(prompt="Press <Enter> to continue...") 
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 2013-01-18
    • 2014-11-05
    • 2021-05-10
    • 1970-01-01
    相关资源
    最近更新 更多