Walter Anderson
2013-Dec-06 15:44 UTC
[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function
I am having trouble understanding how to use sapply (or similar
functions) with a user defined function with multiple parameters.
I have the following functions defined
q1.ans <- function(x)
{
retVal = 0
if (x == 1) {
retVal = 1
} else if (x ==2) {
retVal = 2
}
return (retVal)
}
q2.ans <- function(x)
{
retVal = 0
if (x == 1) {
retVal = 1
} else if (x ==2) {
retVal = 3
}
return (retVal)
}
q3.ans <- function(x)
{
retVal = 0
if (x == 1) {
retVal = 2
} else if (x ==2) {
retVal = 3
}
return (retVal)
}
evaluate.questions <- function(q.1,q.2,q.3)
{
a <- q1.ans(q.1)
b <- q2.ans(q.2)
c <- q3.ans(q.3)
retVal = 0 # Set default value to be no preference
# The following code only implements those values from the state
machine that show a preference (ID's 5,9,11,13-15,17-18,21,23-27)
if (a == 0) {
if (b == 1) {
if (c == 1) {
retVal = 1 # State machine ID 5
}
} else if (b == 2) {
if (c == 2) {
retVal = 2 # State machine ID 9
}
}
} else if (a == 1) {
if (b == 0) {
if (c == 1) {
retVal = 1 # State machine ID 11
}
} else if (b == 1) {
retVal = 1 # State machine ID's 13-15, value of C doesn't
matter
} else if (b == 2) {
if (c == 1) {
retVal = 1 # State machine ID 17
} else if (c == 2) {
retVal = 2 # State machine ID 18
}
}
} else if (a == 2) {
if (b == 0) {
if (c == 2) {
retVal = 2 # State machine ID 21
}
} else if (b == 1) {
if (c == 1) {
retVal = 1 # State machine ID 23
} else if (c == 2) {
retVal = 2 # State machine ID 24
}
} else if (b == 2) {
retVal = 2 # State machine ID's 25-27, value of C doesn't
matter
}
}
return (retVal)
}
And a data set that looks like this:
ID,Q1,Q2,Q3
1,2,2,2
2,2,1,1
3,1,1,1
4,1,2,2
5,2,2,1
6,1,2,1
...
I have been researching and it appears that I should be using the sapply
function to apply the evaluate.question function above to each row in
the data frame like this
preferences <- sapply(df, evaluate.questions, function(x,y,z)
evaluate.questions(df['Q1'],df['Q2'],df['Q3']))
Unfortunately this doesn't work and the problem appears that the sapply
function is not feeding the parameters to the evaluate.questions
function as I expect. Can someone provide some guidance on what I am
doing wrong?
This is the error message I am getting:
Error in x --1 :
Comparison (1) is possible only for atomic and list types
In addition: warning messages:
In if (x == 1) { :
the condition has length > 1 and only the first element will be used
[[alternative HTML version deleted]]
PIKAL Petr
2013-Dec-06 15:59 UTC
[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function
Hi The warning is due to fact that "if" takes only single scalar value not an entire vector. Maybe you shall explain more clearly what result do you expect. I bet that there is vectorised solution to your problem but I am lost in your ifs and cannot follow what shall be the output. Please use dput(head(df)) when showing input data and clearly describe intended result. Regards Petr> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r- > project.org] On Behalf Of Walter Anderson > Sent: Friday, December 06, 2013 4:44 PM > To: r-help at r-project.org > Subject: [R] Need help figuring out sapply (and similar functions) with > multiple parameter user defined function > > I am having trouble understanding how to use sapply (or similar > functions) with a user defined function with multiple parameters. > > I have the following functions defined > > q1.ans <- function(x) > { > retVal = 0 > if (x == 1) { > retVal = 1 > } else if (x ==2) { > retVal = 2 > } > return (retVal) > } > q2.ans <- function(x) > { > retVal = 0 > if (x == 1) { > retVal = 1 > } else if (x ==2) { > retVal = 3 > } > return (retVal) > } > q3.ans <- function(x) > { > retVal = 0 > if (x == 1) { > retVal = 2 > } else if (x ==2) { > retVal = 3 > } > return (retVal) > } > > evaluate.questions <- function(q.1,q.2,q.3) > { > a <- q1.ans(q.1) > b <- q2.ans(q.2) > c <- q3.ans(q.3) > retVal = 0 # Set default value to be no preference > # The following code only implements those values from the state > machine that show a preference (ID's 5,9,11,13-15,17-18,21,23-27) > if (a == 0) { > if (b == 1) { > if (c == 1) { > retVal = 1 # State machine ID 5 > } > } else if (b == 2) { > if (c == 2) { > retVal = 2 # State machine ID 9 > } > } > } else if (a == 1) { > if (b == 0) { > if (c == 1) { > retVal = 1 # State machine ID 11 > } > } else if (b == 1) { > retVal = 1 # State machine ID's 13-15, value of C doesn't > matter > } else if (b == 2) { > if (c == 1) { > retVal = 1 # State machine ID 17 > } else if (c == 2) { > retVal = 2 # State machine ID 18 > } > } > } else if (a == 2) { > if (b == 0) { > if (c == 2) { > retVal = 2 # State machine ID 21 > } > } else if (b == 1) { > if (c == 1) { > retVal = 1 # State machine ID 23 > } else if (c == 2) { > retVal = 2 # State machine ID 24 > } > } else if (b == 2) { > retVal = 2 # State machine ID's 25-27, value of C doesn't > matter > } > } > return (retVal) > } > > And a data set that looks like this: > > ID,Q1,Q2,Q3 > 1,2,2,2 > 2,2,1,1 > 3,1,1,1 > 4,1,2,2 > 5,2,2,1 > 6,1,2,1 > ... > > > I have been researching and it appears that I should be using the > sapply function to apply the evaluate.question function above to each > row in the data frame like this > > preferences <- sapply(df, evaluate.questions, function(x,y,z) > evaluate.questions(df['Q1'],df['Q2'],df['Q3'])) > > Unfortunately this doesn't work and the problem appears that the sapply > function is not feeding the parameters to the evaluate.questions > function as I expect. Can someone provide some guidance on what I am > doing wrong? > > This is the error message I am getting: > > Error in x --1 : > Comparison (1) is possible only for atomic and list types In > addition: warning messages: > In if (x == 1) { : > the condition has length > 1 and only the first element will be used > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting- > guide.html > and provide commented, minimal, self-contained, reproducible code.
William Dunlap
2013-Dec-06 16:43 UTC
[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function
> I have been researching and it appears that I should be using the sapply > function to apply the evaluate.question function above to each row in > the data frame like thisRead the documentation more closely: sapply(dataFrame, func) applies func() to each column, not row, of dataFrame.> preferences <- sapply(df, evaluate.questions, function(x,y,z) > evaluate.questions(df['Q1'],df['Q2'],df['Q3']))Furthermore, sapply(X = dataFrame, FUN = func, extraArgument) calls func(dataFrame[, i], extraArgument) for i in seq_len(ncol(dataFrame). One problem is that FUN=evaluate.questions takes 3 arguments and you give it only 2. Another problem is that the third argument you pass to sapply is a function (of 3 arguments) and FUN is not expecting any of its arguments to be functions. It may be easier for you to not use sapply here, but to use for-loops and come up with something that works. (Write tests that will indicate whether it works or not in a variety of situations.) Then transform it to use things like ifelse() and sapply() to make it more readable and run faster.> Unfortunately this doesn't work and the problem appears that the sapply > function is not feeding the parameters to the evaluate.questions > function as I expect. Can someone provide some guidance on what I am > doing wrong?Bill Dunlap Spotfire, TIBCO Software wdunlap tibco.com> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf > Of Walter Anderson > Sent: Friday, December 06, 2013 7:44 AM > To: r-help at r-project.org > Subject: [R] Need help figuring out sapply (and similar functions) with multiple parameter > user defined function > > I am having trouble understanding how to use sapply (or similar > functions) with a user defined function with multiple parameters. > > I have the following functions defined > > q1.ans <- function(x) > { > retVal = 0 > if (x == 1) { > retVal = 1 > } else if (x ==2) { > retVal = 2 > } > return (retVal) > } > q2.ans <- function(x) > { > retVal = 0 > if (x == 1) { > retVal = 1 > } else if (x ==2) { > retVal = 3 > } > return (retVal) > } > q3.ans <- function(x) > { > retVal = 0 > if (x == 1) { > retVal = 2 > } else if (x ==2) { > retVal = 3 > } > return (retVal) > } > > evaluate.questions <- function(q.1,q.2,q.3) > { > a <- q1.ans(q.1) > b <- q2.ans(q.2) > c <- q3.ans(q.3) > retVal = 0 # Set default value to be no preference > # The following code only implements those values from the state > # machine that show a preference (ID's 5,9,11,13-15,17-18,21,23-27) > if (a == 0) { > if (b == 1) { > if (c == 1) { > retVal = 1 # State machine ID 5 > } > } else if (b == 2) { > if (c == 2) { > retVal = 2 # State machine ID 9 > } > } > } else if (a == 1) { > if (b == 0) { > if (c == 1) { > retVal = 1 # State machine ID 11 > } > } else if (b == 1) { > retVal = 1 # State machine ID's 13-15, value of C doesn't matter > } else if (b == 2) { > if (c == 1) { > retVal = 1 # State machine ID 17 > } else if (c == 2) { > retVal = 2 # State machine ID 18 > } > } > } else if (a == 2) { > if (b == 0) { > if (c == 2) { > retVal = 2 # State machine ID 21 > } > } else if (b == 1) { > if (c == 1) { > retVal = 1 # State machine ID 23 > } else if (c == 2) { > retVal = 2 # State machine ID 24 > } > } else if (b == 2) { > retVal = 2 # State machine ID's 25-27, value of C doesn't matter > } > } > return (retVal) > } > > And a data set that looks like this: > > ID,Q1,Q2,Q3 > 1,2,2,2 > 2,2,1,1 > 3,1,1,1 > 4,1,2,2 > 5,2,2,1 > 6,1,2,1 > ... > > > I have been researching and it appears that I should be using the sapply > function to apply the evaluate.question function above to each row in > the data frame like this > > preferences <- sapply(df, evaluate.questions, function(x,y,z) > evaluate.questions(df['Q1'],df['Q2'],df['Q3'])) > > Unfortunately this doesn't work and the problem appears that the sapply > function is not feeding the parameters to the evaluate.questions > function as I expect. Can someone provide some guidance on what I am > doing wrong? > > This is the error message I am getting: > > Error in x --1 : > Comparison (1) is possible only for atomic and list types > In addition: warning messages: > In if (x == 1) { : > the condition has length > 1 and only the first element will be used > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
PIKAL Petr
2013-Dec-09 15:23 UTC
[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function
Hi You probably missed this Instead of those tricky ifs (uff uff) you can use either of these df[df[,2]==2,2]<-3 df$C<-as.numeric(as.character(factor(df$C, labels=c(0,2,3)))) df A B C 1 0 3 3 2 0 1 2 3 0 3 2 4 1 0 3 5 1 0 3 6 2 3 2 7 1 3 2 8 2 3 3 9 1 1 0 10 0 0 3 And here I am lost again. Please, can you ***clearly*** state the way how do you want to choose preferences based on values in those three columns? Regards Petr Petr Pikal From: Walter Anderson [mailto:wandrson01@gmail.com] Sent: Friday, December 06, 2013 5:32 PM To: PIKAL Petr Subject: RE: [R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function I posted the first 6 rows of my data in the first post. On Dec 6, 2013 10:31 AM, "PIKAL Petr" <petr.pikal@precheza.cz<mailto:petr.pikal@precheza.cz>> wrote: Hi So first step is over. Anyway, is there any problem with using dput as I suggested? Instead of using your date I need to generate my own. A<-sample(0:2, 10, replace=T) B<-sample(0:2, 10, replace=T) C<-sample(0:2, 10, replace=T) df<-data.frame(A,B,C) df[df[,2]==2,2]<-3 df$C<-as.numeric(as.character(factor(df$C, labels=c(0,2,3)))) df A B C 1 0 3 3 2 0 1 2 3 0 3 2 4 1 0 3 5 1 0 3 6 2 3 2 7 1 3 2 8 2 3 3 9 1 1 0 10 0 0 3> -----Original Message----- > From: Walter Anderson [mailto:wandrson01@gmail.com<mailto:wandrson01@gmail.com>] > Sent: Friday, December 06, 2013 5:11 PM > To: PIKAL Petr; r-help@r-project.org<mailto:r-help@r-project.org> > Subject: Re: [R] Need help figuring out sapply (and similar functions) > with multiple parameter user defined function > > Thank you for your response! > > I am attempting to determine a preference from the answers to three > binomial questions; > > q.1) 1 or 2 q.2) 1 or 3 q.3) 2 or 3 > > However, the questions are coded with either a 1 or 2 (though no answer > is also possible) and the first three functions (q#.ans) convert those > values to the 1,2,or 3 shown aboveInstead of those tricky ifs (uff uff) you can use either of these df[df[,2]==2,2]<-3 df$C<-as.numeric(as.character(factor(df$C, labels=c(0,2,3)))) df A B C 1 0 3 3 2 0 1 2 3 0 3 2 4 1 0 3 5 1 0 3 6 2 3 2 7 1 3 2 8 2 3 3 9 1 1 0 10 0 0 3 And here I am lost again. Please, can you clearly state the way how do you want to choose preferences based on values in those three columns. Regards Petr> > and generate one of the following result for each row of the table; 0 - > no preference, or 1,2,3 which indicates the preference indicated by the > question > > The if's implement the following state conditions: > > # ID A B C Preference > # 1 0 0 0 None > # 2 0 0 1 None > # 3 0 0 2 None > # 4 0 1 0 None > # 5 0 1 1 Option 1 > # 6 0 1 2 None > # 7 0 2 0 None > # 8 0 2 1 None > # 9 0 2 2 Option 2 > # 10 1 0 0 None > # 11 1 0 1 Option 1 > # 12 1 0 2 None > # 13 1 1 0 Option 1 > # 14 1 1 1 Option 1 > # 15 1 1 2 Option 1 > # 16 1 2 0 None > # 17 1 2 1 Option 1 > # 18 1 2 2 Option 2 > # 19 2 0 0 None > # 20 2 0 1 None > # 21 2 0 2 Option 2 > # 22 2 1 0 None > # 23 2 1 1 Option 1 > # 24 2 1 2 Option 2 > # 25 2 2 0 Option 2 > # 26 2 2 1 Option 2 > # 27 2 2 2 Option 2 > > The if statement only implements those values from the state machine > that show a preference (ID's 5,9,11,13-15,17-18,21,23-27) > > On 12/06/2013 09:59 AM, PIKAL Petr wrote: > > Hi > > > > The warning is due to fact that "if" takes only single scalar value > not an entire vector. > > > > Maybe you shall explain more clearly what result do you expect. > > > > I bet that there is vectorised solution to your problem but I am lost > in your ifs and cannot follow what shall be the output. > > > > Please use > > > > dput(head(df)) > > > > when showing input data and clearly describe intended result. > > > > Regards > > Petr > > > > > >> -----Original Message----- > >> From: r-help-bounces@r-project.org<mailto:r-help-bounces@r-project.org> [mailto:r-help-bounces@r-<mailto:r-help-bounces@r-> > >> project.org<http://project.org>] On Behalf Of Walter Anderson > >> Sent: Friday, December 06, 2013 4:44 PM > >> To: r-help@r-project.org<mailto:r-help@r-project.org> > >> Subject: [R] Need help figuring out sapply (and similar functions) > >> with multiple parameter user defined function > >> > >> I am having trouble understanding how to use sapply (or similar > >> functions) with a user defined function with multiple parameters. > >> > >> I have the following functions defined > >> > >> q1.ans <- function(x) > >> { > >> retVal = 0 > >> if (x == 1) { > >> retVal = 1 > >> } else if (x ==2) { > >> retVal = 2 > >> } > >> return (retVal) > >> } > >> q2.ans <- function(x) > >> { > >> retVal = 0 > >> if (x == 1) { > >> retVal = 1 > >> } else if (x ==2) { > >> retVal = 3 > >> } > >> return (retVal) > >> } > >> q3.ans <- function(x) > >> { > >> retVal = 0 > >> if (x == 1) { > >> retVal = 2 > >> } else if (x ==2) { > >> retVal = 3 > >> } > >> return (retVal) > >> } > >> > >> evaluate.questions <- function(q.1,q.2,q.3) > >> { > >> a <- q1.ans(q.1) > >> b <- q2.ans(q.2) > >> c <- q3.ans(q.3) > >> retVal = 0 # Set default value to be no preference > >> # The following code only implements those values from the > state > >> machine that show a preference (ID's 5,9,11,13-15,17-18,21,23- > 27) > >> if (a == 0) { > >> if (b == 1) { > >> if (c == 1) { > >> retVal = 1 # State machine ID 5 > >> } > >> } else if (b == 2) { > >> if (c == 2) { > >> retVal = 2 # State machine ID 9 > >> } > >> } > >> } else if (a == 1) { > >> if (b == 0) { > >> if (c == 1) { > >> retVal = 1 # State machine ID 11 > >> } > >> } else if (b == 1) { > >> retVal = 1 # State machine ID's 13-15, value of C > doesn't > >> matter > >> } else if (b == 2) { > >> if (c == 1) { > >> retVal = 1 # State machine ID 17 > >> } else if (c == 2) { > >> retVal = 2 # State machine ID 18 > >> } > >> } > >> } else if (a == 2) { > >> if (b == 0) { > >> if (c == 2) { > >> retVal = 2 # State machine ID 21 > >> } > >> } else if (b == 1) { > >> if (c == 1) { > >> retVal = 1 # State machine ID 23 > >> } else if (c == 2) { > >> retVal = 2 # State machine ID 24 > >> } > >> } else if (b == 2) { > >> retVal = 2 # State machine ID's 25-27, value of C > doesn't > >> matter > >> } > >> } > >> return (retVal) > >> } > >> > >> And a data set that looks like this: > >> > >> ID,Q1,Q2,Q3 > >> 1,2,2,2 > >> 2,2,1,1 > >> 3,1,1,1 > >> 4,1,2,2 > >> 5,2,2,1 > >> 6,1,2,1 > >> ... > >> > >> > >> I have been researching and it appears that I should be using the > >> sapply function to apply the evaluate.question function above to > each > >> row in the data frame like this > >> > >> preferences <- sapply(df, evaluate.questions, function(x,y,z) > >> evaluate.questions(df['Q1'],df['Q2'],df['Q3'])) > >> > >> Unfortunately this doesn't work and the problem appears that the > >> sapply function is not feeding the parameters to the > >> evaluate.questions function as I expect. Can someone provide some > >> guidance on what I am doing wrong? > >> > >> This is the error message I am getting: > >> > >> Error in x --1 : > >> Comparison (1) is possible only for atomic and list types In > >> addition: warning messages: > >> In if (x == 1) { : > >> the condition has length > 1 and only the first element will be > >> used > >> > >> [[alternative HTML version deleted]] > >> > >> ______________________________________________ > >> R-help@r-project.org<mailto:R-help@r-project.org> mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-help > >> PLEASE do read the posting guide http://www.R-project.org/posting- > >> guide.html and provide commented, minimal, self-contained, > >> reproducible code.[[alternative HTML version deleted]]
PIKAL Petr
2013-Dec-09 16:21 UTC
[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function
Hi
you are still rather cryptic. If you said you want to extract prevalent choices
in each row it would save me (and you) a lot of time.
Import data and make necessary chnages
survey.results <- read.csv("SamplePairedComparisonData.csv")
survey.results[survey.results[,3]==2,3]<-3 # Convert column 3 (Q2) to a
value of 3 if the existing value is 2
# The order of the following two commands is important, don't change
survey.results[survey.results[,4]==2,4]<-3 # Convert column 4 (Q3) to a
value of 3 if the existing value is 1
survey.results[survey.results[,4]==1,4]<-2 # Convert column 4 (Q4) to a
value of 2 if the existing value is 1
survey.results$Q1 <- factor(survey.results$Q1,
labels=c("None","Option 1","Option 2"))
survey.results$Q2 <- factor(survey.results$Q2,
labels=c("None","Option 1","Option 3"))
survey.results$Q3 <- factor(survey.results$Q3,
labels=c("None","Option 2","Option 3"))
Then make the object matrix without first column
sr<-survey.results[,-1]
sr<-as.matrix(sr)
Elaborate evaluation function
fff <- function(x) names(which.max(table(x)))
Apply function to matrix
result <- apply(sr,1, fff)
Bind result with original data
survey.results <- cbind(survey.results, result)
And voila, you shall have reqiured values.
Regards
Petr
From: Walter Anderson [mailto:wandrson01@gmail.com]
Sent: Monday, December 09, 2013 4:37 PM
To: PIKAL Petr
Subject: Re: [R] Need help figuring out sapply (and similar functions) with
multiple parameter user defined function
Peter.
First, let me thank you for your assistance on this. Your ideas below for
eliminating the three functions I had that 'adjusted' the data was
received and appreciated. I included that approach in my revised script. I am
only left with a for loop and my final preference determining code. I am
including the current script and test data (all possible choices included-27).
>From my review of all of the responses, I don't see an alternative to
the if then block that tests the state of the three questions or the for loop
that executes it. I made some attempts to use the ifelse statement mentioned in
the responses, but couldn't get anything to work.
Again, thanks for your assistance and time on this!
Walter
On 12/09/2013 09:23 AM, PIKAL Petr wrote:
Hi
You probably missed this
Instead of those tricky ifs (uff uff) you can use either of these
df[df[,2]==2,2]<-3
df$C<-as.numeric(as.character(factor(df$C, labels=c(0,2,3))))
df
A B C
1 0 3 3
2 0 1 2
3 0 3 2
4 1 0 3
5 1 0 3
6 2 3 2
7 1 3 2
8 2 3 3
9 1 1 0
10 0 0 3
And here I am lost again.
Please, can you ***clearly*** state the way how do you want to choose
preferences based on values in those three columns?
Regards
Petr
Petr Pikal
From: Walter Anderson [mailto:wandrson01@gmail.com]
Sent: Friday, December 06, 2013 5:32 PM
To: PIKAL Petr
Subject: RE: [R] Need help figuring out sapply (and similar functions) with
multiple parameter user defined function
I posted the first 6 rows of my data in the first post.
On Dec 6, 2013 10:31 AM, "PIKAL Petr"
<petr.pikal@precheza.cz<mailto:petr.pikal@precheza.cz>> wrote:
Hi
So first step is over. Anyway, is there any problem with using dput as I
suggested?
Instead of using your date I need to generate my own.
A<-sample(0:2, 10, replace=T)
B<-sample(0:2, 10, replace=T)
C<-sample(0:2, 10, replace=T)
df<-data.frame(A,B,C)
df[df[,2]==2,2]<-3
df$C<-as.numeric(as.character(factor(df$C, labels=c(0,2,3))))
df
A B C
1 0 3 3
2 0 1 2
3 0 3 2
4 1 0 3
5 1 0 3
6 2 3 2
7 1 3 2
8 2 3 3
9 1 1 0
10 0 0 3
> -----Original Message-----
> From: Walter Anderson
[mailto:wandrson01@gmail.com<mailto:wandrson01@gmail.com>]
> Sent: Friday, December 06, 2013 5:11 PM
> To: PIKAL Petr; r-help@r-project.org<mailto:r-help@r-project.org>
> Subject: Re: [R] Need help figuring out sapply (and similar functions)
> with multiple parameter user defined function
>
> Thank you for your response!
>
> I am attempting to determine a preference from the answers to three
> binomial questions;
>
> q.1) 1 or 2 q.2) 1 or 3 q.3) 2 or 3
>
> However, the questions are coded with either a 1 or 2 (though no answer
> is also possible) and the first three functions (q#.ans) convert those
> values to the 1,2,or 3 shown above
Instead of those tricky ifs (uff uff) you can use either of these
df[df[,2]==2,2]<-3
df$C<-as.numeric(as.character(factor(df$C, labels=c(0,2,3))))
df
A B C
1 0 3 3
2 0 1 2
3 0 3 2
4 1 0 3
5 1 0 3
6 2 3 2
7 1 3 2
8 2 3 3
9 1 1 0
10 0 0 3
And here I am lost again.
Please, can you clearly state the way how do you want to choose preferences
based on values in those three columns.
Regards
Petr
>
> and generate one of the following result for each row of the table; 0 -
> no preference, or 1,2,3 which indicates the preference indicated by the
> question
>
> The if's implement the following state conditions:
>
> # ID A B C Preference
> # 1 0 0 0 None
> # 2 0 0 1 None
> # 3 0 0 2 None
> # 4 0 1 0 None
> # 5 0 1 1 Option 1
> # 6 0 1 2 None
> # 7 0 2 0 None
> # 8 0 2 1 None
> # 9 0 2 2 Option 2
> # 10 1 0 0 None
> # 11 1 0 1 Option 1
> # 12 1 0 2 None
> # 13 1 1 0 Option 1
> # 14 1 1 1 Option 1
> # 15 1 1 2 Option 1
> # 16 1 2 0 None
> # 17 1 2 1 Option 1
> # 18 1 2 2 Option 2
> # 19 2 0 0 None
> # 20 2 0 1 None
> # 21 2 0 2 Option 2
> # 22 2 1 0 None
> # 23 2 1 1 Option 1
> # 24 2 1 2 Option 2
> # 25 2 2 0 Option 2
> # 26 2 2 1 Option 2
> # 27 2 2 2 Option 2
>
> The if statement only implements those values from the state machine
> that show a preference (ID's 5,9,11,13-15,17-18,21,23-27)
>
> On 12/06/2013 09:59 AM, PIKAL Petr wrote:
> > Hi
> >
> > The warning is due to fact that "if" takes only single
scalar value
> not an entire vector.
> >
> > Maybe you shall explain more clearly what result do you expect.
> >
> > I bet that there is vectorised solution to your problem but I am lost
> in your ifs and cannot follow what shall be the output.
> >
> > Please use
> >
> > dput(head(df))
> >
> > when showing input data and clearly describe intended result.
> >
> > Regards
> > Petr
> >
> >
> >> -----Original Message-----
> >> From:
r-help-bounces@r-project.org<mailto:r-help-bounces@r-project.org>
[mailto:r-help-bounces@r-<mailto:r-help-bounces@r->
> >> project.org<http://project.org>] On Behalf Of Walter
Anderson
> >> Sent: Friday, December 06, 2013 4:44 PM
> >> To: r-help@r-project.org<mailto:r-help@r-project.org>
> >> Subject: [R] Need help figuring out sapply (and similar functions)
> >> with multiple parameter user defined function
> >>
> >> I am having trouble understanding how to use sapply (or similar
> >> functions) with a user defined function with multiple parameters.
> >>
> >> I have the following functions defined
> >>
> >> q1.ans <- function(x)
> >> {
> >> retVal = 0
> >> if (x == 1) {
> >> retVal = 1
> >> } else if (x ==2) {
> >> retVal = 2
> >> }
> >> return (retVal)
> >> }
> >> q2.ans <- function(x)
> >> {
> >> retVal = 0
> >> if (x == 1) {
> >> retVal = 1
> >> } else if (x ==2) {
> >> retVal = 3
> >> }
> >> return (retVal)
> >> }
> >> q3.ans <- function(x)
> >> {
> >> retVal = 0
> >> if (x == 1) {
> >> retVal = 2
> >> } else if (x ==2) {
> >> retVal = 3
> >> }
> >> return (retVal)
> >> }
> >>
> >> evaluate.questions <- function(q.1,q.2,q.3)
> >> {
> >> a <- q1.ans(q.1)
> >> b <- q2.ans(q.2)
> >> c <- q3.ans(q.3)
> >> retVal = 0 # Set default value to be no preference
> >> # The following code only implements those values from the
> state
> >> machine that show a preference (ID's
5,9,11,13-15,17-18,21,23-
> 27)
> >> if (a == 0) {
> >> if (b == 1) {
> >> if (c == 1) {
> >> retVal = 1 # State machine ID 5
> >> }
> >> } else if (b == 2) {
> >> if (c == 2) {
> >> retVal = 2 # State machine ID 9
> >> }
> >> }
> >> } else if (a == 1) {
> >> if (b == 0) {
> >> if (c == 1) {
> >> retVal = 1 # State machine ID 11
> >> }
> >> } else if (b == 1) {
> >> retVal = 1 # State machine ID's 13-15, value of
C
> doesn't
> >> matter
> >> } else if (b == 2) {
> >> if (c == 1) {
> >> retVal = 1 # State machine ID 17
> >> } else if (c == 2) {
> >> retVal = 2 # State machine ID 18
> >> }
> >> }
> >> } else if (a == 2) {
> >> if (b == 0) {
> >> if (c == 2) {
> >> retVal = 2 # State machine ID 21
> >> }
> >> } else if (b == 1) {
> >> if (c == 1) {
> >> retVal = 1 # State machine ID 23
> >> } else if (c == 2) {
> >> retVal = 2 # State machine ID 24
> >> }
> >> } else if (b == 2) {
> >> retVal = 2 # State machine ID's 25-27, value of
C
> doesn't
> >> matter
> >> }
> >> }
> >> return (retVal)
> >> }
> >>
> >> And a data set that looks like this:
> >>
> >> ID,Q1,Q2,Q3
> >> 1,2,2,2
> >> 2,2,1,1
> >> 3,1,1,1
> >> 4,1,2,2
> >> 5,2,2,1
> >> 6,1,2,1
> >> ...
> >>
> >>
> >> I have been researching and it appears that I should be using the
> >> sapply function to apply the evaluate.question function above to
> each
> >> row in the data frame like this
> >>
> >> preferences <- sapply(df, evaluate.questions, function(x,y,z)
> >>
evaluate.questions(df['Q1'],df['Q2'],df['Q3']))
> >>
> >> Unfortunately this doesn't work and the problem appears that
the
> >> sapply function is not feeding the parameters to the
> >> evaluate.questions function as I expect. Can someone provide some
> >> guidance on what I am doing wrong?
> >>
> >> This is the error message I am getting:
> >>
> >> Error in x --1 :
> >> Comparison (1) is possible only for atomic and list types In
> >> addition: warning messages:
> >> In if (x == 1) { :
> >> the condition has length > 1 and only the first element
will be
> >> used
> >>
> >> [[alternative HTML version deleted]]
> >>
> >> ______________________________________________
> >> R-help@r-project.org<mailto:R-help@r-project.org> mailing
list
> >> https://stat.ethz.ch/mailman/listinfo/r-help
> >> PLEASE do read the posting guide http://www.R-project.org/posting-
> >> guide.html and provide commented, minimal, self-contained,
> >> reproducible code.
[[alternative HTML version deleted]]
Walter Anderson
2013-Dec-09 20:40 UTC
[R] Need help figuring out sapply (and similar functions) with multiple parameter user defined function
Karen,
Thank you for your reply. That approach makes the code for determining
preference much clearer. Unfortunately, it appears I am still needing
to use a for loop to process each row.
For any who find these posts and may have similar questions, I am
including my current code and sample data to provide a working solution:
survey.results <- read.csv("SamplePairedComparisonData.csv")
# The following function evaluates which, if any, preference the
respondent has shown
get.pref <- function(x)
{
# names(which.max(table(x)))
n.1 <- sum(x==1) # Calculate the number of times the respondent chose
option 1
n.2 <- sum(x==2) # Calculate the number of times the respondent chose
option 2
n.3 <- sum(x==3) # Calculate the number of times the respondent chose
option 3
retVal <- "None"
if (n.1 >= 2) {
retVal <- "Option 1"
} else if (n.2 >= 2) {
retVal <- "Option 2"
} else if (n.3 >= 2) {
retVal <- "Option 3"
}
return(retVal)
}
# The data is expected to be organized as so:
# ID, Q1, Q2, Q3
# and that the questions are in the following format
# Q.1) Which do you prefer?
# 1) Option 1
# 2) Option 2
# Q.2) Which do you prefer?
# 1) Option 1
# 2) Option 3
# Q.3) Which do you prefer?
# 1) Option 2
# 2) Option 3
# And the next three lines reprocess the data table to organize the
questions so that the values for Q.2) are 1 or 3 and the values for Q.3)
are 2 or 3
survey.results[survey.results[,3]==2,3]<-3 # Convert column 3 (Q2) to a
value of 3 if the existing value is 2
# The order of the following two commands is important, don't change
survey.results[survey.results[,4]==2,4]<-3 # Convert column 4 (Q3) to a
value of 3 if the existing value is 1
survey.results[survey.results[,4]==1,4]<-2 # Convert column 4 (Q3) to a
value of 2 if the existing value is 1
for (indx in 1:length(survey.results$ID))
{
survey.results$Preference[indx] <- get.pref(survey.results[indx, 2:4])
}
# The following lines convert the numerical values in the fields to text
(factors)
# If the questions don't have empty (zero) values than the "None"
should
be removed from those questions where zero isn't possible
survey.results$Q1 <- factor(survey.results$Q1,
labels=c("None","Option 1","Option 2"))
survey.results$Q2 <- factor(survey.results$Q2,
labels=c("None","Option 1","Option 3"))
survey.results$Q3 <- factor(survey.results$Q3,
labels=c("None","Option 2","Option 3"))
# survey.results$Preference <-
apply(as.matrix(survey.results[,-1]),1,get.pref)
and here is the sample data.
#The following sample data represents every possible response to the
three questions of the type described above
ID,Q1,Q2,Q3
1,0,0,0
2,0,0,1
3,0,0,2
4,0,1,0
5,0,1,1
6,0,1,2
7,0,2,0
8,0,2,1
9,0,2,2
10,1,0,0
11,1,0,1
12,1,0,2
13,1,1,0
14,1,1,1
15,1,1,2
16,1,2,0
17,1,2,1
18,1,2,2
19,2,0,0
20,2,0,1
21,2,0,2
22,2,1,0
23,2,1,1
24,2,1,2
25,2,2,0
26,2,2,1
27,2,2,2
On 12/09/2013 09:42 AM, Karen Keating wrote:> Hi Walter,
> From your list of preferences, it seems that Option 2 is preferred if
> there are at least two 2's for the ID, and Option 1 is preferred if
> there are at least two 1's for the ID. If neither of these conditions
> are met, then there is no preference. If this interpretation is
> correct, I would suggest replacing your list of 'if' statements
with
> the following:
>
> get.pref<-function(x) {
> n.1<-sum(x==1)
> n.2<-sum(x==2)
> pref='None'
> if(n.1>=2) {pref='Option 1'} else
> if(n.2>=2) {pref='Option 2'}
> pref
> }
> R-help@r-project.org <mailto:R-help@r-project.org> mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide
> http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
[[alternative HTML version deleted]]