2014-09-18 10 views
0

Я делаю систематические вычисления для моего созданного фрейма данных. У меня есть код для вычислений, но я хотел бы:Создание функции для обработки вычислений моих данных.

1) Рассказать об этом как о функции и вызвать ее для созданного ядро ​​DataFrame.

2) сбросьте вычисления для следующего идентификатора в кадре данных.

Буду признателен за вашу помощь и советы по этому вопросу.

dataframe создается в 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 для всех временных точек. Если субъект ID = 2, когда WT (вес) изменяется на 120. Как я могу сбросить вычисления и сделать его автоматизированным для всех идентификаторов объекта в кадре данных? В этом случае исходная датаграмма будет выглядеть так:

#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)) 

Заранее благодарю вас!

+0

Итак, какая часть этого вы не знаете, как это сделать? Где актуальный вопрос программирования? Сейчас кажется, что это всего лишь просьба «сделай это для меня». – MrFlick

+0

1. Я хотел бы написать for-loop как функцию, чтобы я мог назвать ее для dataframes; как df2 <- calculate.func (df). – Amer

+0

2: Я не знаю, как сбросить вычисления для следующего идентификатора объекта. (т. е. повторите те же вычисления для ID = 2, начиная с TIME = 0 для ID2) @MrFlick – Amer

ответ

0

В целом, при выполнении расчетов по данным различных субъекта, мне нравится разделить dataframe по 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) 
+0

Спасибо @skotturi. Я протестировал его, он фактически делает неправильные вычисления. Похоже, что мой вопрос мой вопрос был недостаточно ясным. Я снова задал новый вопрос, который более ясен, чего я хочу достичь. Я был бы признателен, если бы вы могли взглянуть на него. (http://stackoverflow.com/questions/25908142/how-to-write-the-for-loop-into-a-function-how-to-apply-it-by-subject-id) – Amer

+0

Похоже, вы получили ответ, который работает для вас. Я должен указать, что ответ на этот вопрос делает то же самое, что и в этом ответе, он разбивает данные по теме, выполняет все вычисления, которые вы хотите (вы, кажется, добавили пару переменных), а затем помещает весь файл данных обратно вместе , Там есть причудливый пакет для этого, называемый plyr, хотя, когда люди учатся, RI обычно рекомендуют писать все вручную, потому что легче видеть, что происходит (вместо того, чтобы делать нерасщепленный (lappply (split (data, func))) Все они работают, просто зависит от того, что помогает вам лучше учиться. – skotturi

+0

Благодарим вас за помощь и рекомендации. Вы абсолютно правы, написав код вручную и понимая, что это помогает. Честно говоря, мне всегда трудно понять (применять) семейные функции. Я узнаю немного больше день за днем ​​=) – Amer

0

Вы хотите:

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...") 
} 
Смежные вопросы