0
data = data.frame(
focal = c("John","John","John","John","Albert","Charles","Charles","Jay","Jay","Jay"),
type = c("Baseline","Baseline","Baseline","Baseline","Experimental","Experimental","Experimental","Baseline","Baseline","Baseline"),
partner5M = c("Martin","Albert","Chris","Chris","John","Albert","Rich","Martin","Albert","Alfred"),
duration = sample(c(1:50),10),
header = TRUE
)

I need to extract data from my data frame as follows (it works) :

Xindiv = database[ which ( data$focal == "John" & data$type == "Baseline" & database$partner5M == "indiv"),4]
Xindiv = unlist(Xindiv,use.names = FALSE)
Xindiv = chron(times = Xindiv)

The problem is that I need to do that for a lot of individuals, and I also need to be able to quickly change the conditions in the which.

So what I would like to do is a for loop which would roughly be as follows :

indiv = c("indiv1","indiv2","indiv3") #every different individuals in partner5M
for(indiv in length(indiv)) {

Xindiv = database[ which ( database$Focal == "JohnDoe" & database$Type == "Baseline" & database$Partner5m == "indiv"),24]
Xindiv = unlist(Xindiv,use.names = FALSE)
Xindiv = chron(times = Xindiv)
}

I would like the outcome of this to be :

Xindiv1 = ...
Xindiv2 = ...
Xindiv3 = ...

and so on, but I have no clue as to how to make such a loop, so I would be extremely grateful for any advices on the method.

Cheers, Max

Max
  • 3
  • 3
  • 1
    store it in a list (`Xindiv[indiv]`) which you can declare outside the loop – yeedle May 05 '17 at 13:26
  • 1
    What do you mean by "quickly change the conditions"? Different "Focal", "Type", and "Partner5m" values? You'd need that data as an input as well. I suspect what you really want is to create a data frame of your requirements and [merge](http://stackoverflow.com/questions/1299871/how-to-join-merge-data-frames-inner-outer-left-right) them. But a [reproducible example of your data](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) would help people answer. – David Robinson May 05 '17 at 13:29
  • Yes, that is what I mean, and also add some more conditions, such as the date. My original database is very big, so I'll try to provide a lighter version of it, with only the crucial variables (most are strings btw) – Max May 05 '17 at 13:37

1 Answers1

1

Hopefully reproducing what you are looking for given that I have very little background information about the possibilities.

#install.packages("chron")
library(chron)

data = data.frame(
  focal = c("John","John","John","John","Albert","Charles","Charles","Jay","Jay","Alfred"),
  type = c("Baseline","Baseline","Baseline","Baseline","Experimental","Experimental","Experimental","Baseline","Baseline","Baseline"),
  partner5M = c("Martin","Albert","Chris","John","Chris","Albert","Rich","Martin","Albert","Alfred"),
  duration = sample(c(1:50),10),
  header = TRUE, 
  stringsAsFactors = FALSE # added this because you want characters for easy comaprisons
)
database <- data # to keep your desired naming
database # you will notice I edited it
#     focal         type partner5M duration header
#1     John     Baseline    Martin       37   TRUE
#2     John     Baseline    Albert       41   TRUE
#3     John     Baseline     Chris       18   TRUE
#4     John     Baseline      John       50   TRUE
#5   Albert Experimental     Chris       27   TRUE
#6  Charles Experimental    Albert        4   TRUE
#7  Charles Experimental      Rich       39   TRUE
#8      Jay     Baseline    Martin       13   TRUE
#9      Jay     Baseline    Albert       28   TRUE
#10  Alfred     Baseline    Alfred        6   TRUE

indiv = unique(database[,"partner5M"]) # every different individual in partner5M
indiv
# [1] "Martin" "Albert" "Chris"  "John"   "Rich"   "Alfred"

# You seek to make 
indivs <- database[which(database[,"focal"] == database[,"partner5M"] & 
        database[,"type"] == "Baseline"), c("partner5M","duration")]
#   partner5M duration
#4       John       50
#10    Alfred        6

ls() # See what objects are loaded in your environment
#[1] "data"     "database" "indiv"    "indivs" 

for(i in 1:nrow(indivs)){
  assign(indivs[i,1], chron(times = unlist(indivs[i,2], use.names = F)))
}
ls()
#[1] "Alfred"   "data"     "database" "i"        "indiv"    "indivs"   "John"   

John
#Time in days:
#[1] 30

I believe making a new object as you asked will end up filling your environment. A much better way would be to make a single object/list that carries all the values you are interested in:

xindiv <- sapply(indiv, function(x) {
  xi = chron(times = database[which(database[,"focal"] == x & 
                                                 database[,"partner5M"] == x & 
                                                 database[,"type"] == "Baseline"),"duration"])
  xi
})
xindiv <- xindiv[sapply(xindiv, length) != 0]
xindiv
#$John
#Time in days:
#[1] 30
#
#$Alfred
#Time in days:
#[1] 23
Evan Friedland
  • 3,062
  • 1
  • 11
  • 25
  • You're desired output still leaves me guessing. Are you explicitly looking to make new objects in your environment of the chron(duration column)? Or a single object like a list? – Evan Friedland May 09 '17 at 21:59
  • That is very useful, thank you very much. After slight modifications it all works nicely :). So again, thanks! I do need to create objects in the environment. But thanks anyway for the list option! – Max May 12 '17 at 15:50
  • My pleasure, if this has sufficiently answered your question please click the check symbol to the left of the post~ – Evan Friedland May 12 '17 at 15:56