How to create a sampled choice set for a discrete-choice model using data.table?
I want to estimate a discrete choice model. I have a dataset with people, their current choices at t_1
, their choices at t_2
and all possible choices. Since the universe of possible choices is too large, I need to sample so that each person has 30 choices in their choice set. It has to be sampling without replacement and no individual may have duplicate options in the choice set. Both the actual choice at t_2
and the choice at t_1
need to be part of the choice set. Right now I'm trying something like this, with fictional data.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,"current_choice":=sample(choices,1),by="ID"] #what the person uses now
people[,"chosen":=sample(choices,1),by="ID"] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,"choice_id":=seq_len(.N), by="ID"]
#The current choice at t_1 needs to be in the choice set
people[1,"choice_set":=current_choice,by="ID"]
#The actual choice needs to be in the choice set
people[choice_id==2¤t_choice!=chosen,"choice_set":= chosen,by="ID"]
#I want the remaining choices to be sampled from the vector of choices, but here is where I'm stuck
people[is.na(choice_set),"choice_set":=sample(choices,1),by="ID]
That last line doesn't prevent duplicate choices within each individual, including duplicating the current and the chosen alternatives.
I have thought about using expand.grid
to create all combinations of current choices and potential choices, assigning a random uniform number to them, assigning an even larger number for the rows that have either the current choice or the actual choice, sorting, and then keeping the top 30 rows. The problem is that I run out of memory with the actual 10000 people and 50000 choices.
How should I approach this?
EDIT: After the first answer by Matt, I still come into issues with repeated alternatives in the choice set. I have been trying to solve them with:
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen:= sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The chosen alternative has to be in the choice set
people[choice_id==1L,choice_set:=chosen,by=.(ID) ]
people
#The current chosen alternative has to be in the choice set
people[current_choice!=chosen&choice_id==2L,choice_set:=current_choice,by=.(ID) ]
people
people[is.na(choice_set), choice_set := sample(setdiff(choices,unique(choice_set)), .N), by = .(ID)]
The problem then is that I introduce a missing for those individuals who picked their current choice at t_1
again at t_2
.
r data.table
add a comment |
I want to estimate a discrete choice model. I have a dataset with people, their current choices at t_1
, their choices at t_2
and all possible choices. Since the universe of possible choices is too large, I need to sample so that each person has 30 choices in their choice set. It has to be sampling without replacement and no individual may have duplicate options in the choice set. Both the actual choice at t_2
and the choice at t_1
need to be part of the choice set. Right now I'm trying something like this, with fictional data.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,"current_choice":=sample(choices,1),by="ID"] #what the person uses now
people[,"chosen":=sample(choices,1),by="ID"] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,"choice_id":=seq_len(.N), by="ID"]
#The current choice at t_1 needs to be in the choice set
people[1,"choice_set":=current_choice,by="ID"]
#The actual choice needs to be in the choice set
people[choice_id==2¤t_choice!=chosen,"choice_set":= chosen,by="ID"]
#I want the remaining choices to be sampled from the vector of choices, but here is where I'm stuck
people[is.na(choice_set),"choice_set":=sample(choices,1),by="ID]
That last line doesn't prevent duplicate choices within each individual, including duplicating the current and the chosen alternatives.
I have thought about using expand.grid
to create all combinations of current choices and potential choices, assigning a random uniform number to them, assigning an even larger number for the rows that have either the current choice or the actual choice, sorting, and then keeping the top 30 rows. The problem is that I run out of memory with the actual 10000 people and 50000 choices.
How should I approach this?
EDIT: After the first answer by Matt, I still come into issues with repeated alternatives in the choice set. I have been trying to solve them with:
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen:= sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The chosen alternative has to be in the choice set
people[choice_id==1L,choice_set:=chosen,by=.(ID) ]
people
#The current chosen alternative has to be in the choice set
people[current_choice!=chosen&choice_id==2L,choice_set:=current_choice,by=.(ID) ]
people
people[is.na(choice_set), choice_set := sample(setdiff(choices,unique(choice_set)), .N), by = .(ID)]
The problem then is that I introduce a missing for those individuals who picked their current choice at t_1
again at t_2
.
r data.table
add a comment |
I want to estimate a discrete choice model. I have a dataset with people, their current choices at t_1
, their choices at t_2
and all possible choices. Since the universe of possible choices is too large, I need to sample so that each person has 30 choices in their choice set. It has to be sampling without replacement and no individual may have duplicate options in the choice set. Both the actual choice at t_2
and the choice at t_1
need to be part of the choice set. Right now I'm trying something like this, with fictional data.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,"current_choice":=sample(choices,1),by="ID"] #what the person uses now
people[,"chosen":=sample(choices,1),by="ID"] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,"choice_id":=seq_len(.N), by="ID"]
#The current choice at t_1 needs to be in the choice set
people[1,"choice_set":=current_choice,by="ID"]
#The actual choice needs to be in the choice set
people[choice_id==2¤t_choice!=chosen,"choice_set":= chosen,by="ID"]
#I want the remaining choices to be sampled from the vector of choices, but here is where I'm stuck
people[is.na(choice_set),"choice_set":=sample(choices,1),by="ID]
That last line doesn't prevent duplicate choices within each individual, including duplicating the current and the chosen alternatives.
I have thought about using expand.grid
to create all combinations of current choices and potential choices, assigning a random uniform number to them, assigning an even larger number for the rows that have either the current choice or the actual choice, sorting, and then keeping the top 30 rows. The problem is that I run out of memory with the actual 10000 people and 50000 choices.
How should I approach this?
EDIT: After the first answer by Matt, I still come into issues with repeated alternatives in the choice set. I have been trying to solve them with:
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen:= sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The chosen alternative has to be in the choice set
people[choice_id==1L,choice_set:=chosen,by=.(ID) ]
people
#The current chosen alternative has to be in the choice set
people[current_choice!=chosen&choice_id==2L,choice_set:=current_choice,by=.(ID) ]
people
people[is.na(choice_set), choice_set := sample(setdiff(choices,unique(choice_set)), .N), by = .(ID)]
The problem then is that I introduce a missing for those individuals who picked their current choice at t_1
again at t_2
.
r data.table
I want to estimate a discrete choice model. I have a dataset with people, their current choices at t_1
, their choices at t_2
and all possible choices. Since the universe of possible choices is too large, I need to sample so that each person has 30 choices in their choice set. It has to be sampling without replacement and no individual may have duplicate options in the choice set. Both the actual choice at t_2
and the choice at t_1
need to be part of the choice set. Right now I'm trying something like this, with fictional data.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,"current_choice":=sample(choices,1),by="ID"] #what the person uses now
people[,"chosen":=sample(choices,1),by="ID"] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,"choice_id":=seq_len(.N), by="ID"]
#The current choice at t_1 needs to be in the choice set
people[1,"choice_set":=current_choice,by="ID"]
#The actual choice needs to be in the choice set
people[choice_id==2¤t_choice!=chosen,"choice_set":= chosen,by="ID"]
#I want the remaining choices to be sampled from the vector of choices, but here is where I'm stuck
people[is.na(choice_set),"choice_set":=sample(choices,1),by="ID]
That last line doesn't prevent duplicate choices within each individual, including duplicating the current and the chosen alternatives.
I have thought about using expand.grid
to create all combinations of current choices and potential choices, assigning a random uniform number to them, assigning an even larger number for the rows that have either the current choice or the actual choice, sorting, and then keeping the top 30 rows. The problem is that I run out of memory with the actual 10000 people and 50000 choices.
How should I approach this?
EDIT: After the first answer by Matt, I still come into issues with repeated alternatives in the choice set. I have been trying to solve them with:
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen:= sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The chosen alternative has to be in the choice set
people[choice_id==1L,choice_set:=chosen,by=.(ID) ]
people
#The current chosen alternative has to be in the choice set
people[current_choice!=chosen&choice_id==2L,choice_set:=current_choice,by=.(ID) ]
people
people[is.na(choice_set), choice_set := sample(setdiff(choices,unique(choice_set)), .N), by = .(ID)]
The problem then is that I introduce a missing for those individuals who picked their current choice at t_1
again at t_2
.
r data.table
r data.table
edited Nov 14 '18 at 8:52
Kenji
asked Nov 12 '18 at 20:44
KenjiKenji
339312
339312
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Here's how I would approach the problem as I understand it, using 99% code you already presented (with some aesthetic syntax tweaks here and there, mostly removing un-needed quotes around column assignments and using data.table
's handy .(...)
syntax in the by
statements to eliminate those quotes as well).
The main thing I think will help you is the setdiff()
function from base R
(see help file by running ?base::setdiff
) to make sure that the current_choice
and the chosen
value are excluded from your sampling to fill in the remaining rows after you populate the first two.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen := sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The current choice at t_1 needs to be in the choice set
## the `choice_id == 1L` is critical here, filtering by just `people[1, ...]` wasn't giving
## the result you were actually going for
people[choice_id == 1L, choice_set := current_choice, by=.(ID)]
#The actual choice needs to be in the choice set
people[choice_id == 2L
& current_choice != chosen, choice_set := chosen, by= .(ID)]
## Use setdiff to make sure we sample the rest from a vector excluding the
## `current_choice` and `chosen` values
people[choice_id > 2L, choice_set := sample(setdiff(choices,c(current_choice,chosen)), .N), by = .(ID)]
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53269820%2fhow-to-create-a-sampled-choice-set-for-a-discrete-choice-model-using-data-table%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Here's how I would approach the problem as I understand it, using 99% code you already presented (with some aesthetic syntax tweaks here and there, mostly removing un-needed quotes around column assignments and using data.table
's handy .(...)
syntax in the by
statements to eliminate those quotes as well).
The main thing I think will help you is the setdiff()
function from base R
(see help file by running ?base::setdiff
) to make sure that the current_choice
and the chosen
value are excluded from your sampling to fill in the remaining rows after you populate the first two.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen := sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The current choice at t_1 needs to be in the choice set
## the `choice_id == 1L` is critical here, filtering by just `people[1, ...]` wasn't giving
## the result you were actually going for
people[choice_id == 1L, choice_set := current_choice, by=.(ID)]
#The actual choice needs to be in the choice set
people[choice_id == 2L
& current_choice != chosen, choice_set := chosen, by= .(ID)]
## Use setdiff to make sure we sample the rest from a vector excluding the
## `current_choice` and `chosen` values
people[choice_id > 2L, choice_set := sample(setdiff(choices,c(current_choice,chosen)), .N), by = .(ID)]
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
add a comment |
Here's how I would approach the problem as I understand it, using 99% code you already presented (with some aesthetic syntax tweaks here and there, mostly removing un-needed quotes around column assignments and using data.table
's handy .(...)
syntax in the by
statements to eliminate those quotes as well).
The main thing I think will help you is the setdiff()
function from base R
(see help file by running ?base::setdiff
) to make sure that the current_choice
and the chosen
value are excluded from your sampling to fill in the remaining rows after you populate the first two.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen := sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The current choice at t_1 needs to be in the choice set
## the `choice_id == 1L` is critical here, filtering by just `people[1, ...]` wasn't giving
## the result you were actually going for
people[choice_id == 1L, choice_set := current_choice, by=.(ID)]
#The actual choice needs to be in the choice set
people[choice_id == 2L
& current_choice != chosen, choice_set := chosen, by= .(ID)]
## Use setdiff to make sure we sample the rest from a vector excluding the
## `current_choice` and `chosen` values
people[choice_id > 2L, choice_set := sample(setdiff(choices,c(current_choice,chosen)), .N), by = .(ID)]
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
add a comment |
Here's how I would approach the problem as I understand it, using 99% code you already presented (with some aesthetic syntax tweaks here and there, mostly removing un-needed quotes around column assignments and using data.table
's handy .(...)
syntax in the by
statements to eliminate those quotes as well).
The main thing I think will help you is the setdiff()
function from base R
(see help file by running ?base::setdiff
) to make sure that the current_choice
and the chosen
value are excluded from your sampling to fill in the remaining rows after you populate the first two.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen := sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The current choice at t_1 needs to be in the choice set
## the `choice_id == 1L` is critical here, filtering by just `people[1, ...]` wasn't giving
## the result you were actually going for
people[choice_id == 1L, choice_set := current_choice, by=.(ID)]
#The actual choice needs to be in the choice set
people[choice_id == 2L
& current_choice != chosen, choice_set := chosen, by= .(ID)]
## Use setdiff to make sure we sample the rest from a vector excluding the
## `current_choice` and `chosen` values
people[choice_id > 2L, choice_set := sample(setdiff(choices,c(current_choice,chosen)), .N), by = .(ID)]
Here's how I would approach the problem as I understand it, using 99% code you already presented (with some aesthetic syntax tweaks here and there, mostly removing un-needed quotes around column assignments and using data.table
's handy .(...)
syntax in the by
statements to eliminate those quotes as well).
The main thing I think will help you is the setdiff()
function from base R
(see help file by running ?base::setdiff
) to make sure that the current_choice
and the chosen
value are excluded from your sampling to fill in the remaining rows after you populate the first two.
library(data.table)
#Create the fictional data up to the current choice.
choices<-c(1:100) #vector of possible choices
people<-data.frame(ID=1:10)
setDT(people,key="ID")
people[,current_choice:=sample(choices,1),by= .(ID)] #what the person uses now
people[,chosen := sample(choices,1),by= .(ID)] #what the person actually picked at t_2
#expand the dataset to be 30 rows per person and create a choice ID
people<-people[rep(1:.N,30),]
setDT(people,key="ID")
people[,choice_id:=seq_len(.N), by=.(ID)]
#The current choice at t_1 needs to be in the choice set
## the `choice_id == 1L` is critical here, filtering by just `people[1, ...]` wasn't giving
## the result you were actually going for
people[choice_id == 1L, choice_set := current_choice, by=.(ID)]
#The actual choice needs to be in the choice set
people[choice_id == 2L
& current_choice != chosen, choice_set := chosen, by= .(ID)]
## Use setdiff to make sure we sample the rest from a vector excluding the
## `current_choice` and `chosen` values
people[choice_id > 2L, choice_set := sample(setdiff(choices,c(current_choice,chosen)), .N), by = .(ID)]
answered Nov 12 '18 at 23:34
Matt SummersgillMatt Summersgill
1,906323
1,906323
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
add a comment |
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
This is almost what I needed. I still get repeated entries in the choice set if the current choice and the chosen alternative are the same, though. I'll edit my question to show how I have been trying to fix it building on your answer.
– Kenji
Nov 14 '18 at 8:48
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53269820%2fhow-to-create-a-sampled-choice-set-for-a-discrete-choice-model-using-data-table%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown