Luca Luca - 2 years ago 79
R Question

How to refer to another column of a df in the function inside lapply?

sample df:

dat <- data.frame(position = c("A", "B", "B", "A", "B", "A"),
choice = c("A", "A", "B", "B", "A", "B"))

position choice
1 A A
2 B A
3 B B
4 A B
5 B A
6 A B

I am trying to make another column in the dataframe so that if the two columns "position" and "choice" have the same alphabetic value, then the new column will say something, if not it will say something else:

position choice value
1 A A ok
2 B A no
3 B B ok
4 A B no
5 B A no
6 A B no

So far I tried to make a new column with the same value of "choice" and then using lapply or sapply to replace the values with a conditional like this:

dat$value <- dat$choice

dat$choice[] <- lapply(dat$choice, function(x)
ifelse(x == dat$position, "ok", x))

But it doesn't seem to work, there must be something wrong with the way I referred to "position". In fact it replaces all the values with the whole "position" column as a vector instead of the values one by one -- e.g. output: c("A", "A", "ok", "ok", "A", "ok") or viceversa c("ok", "ok", "B", "B", "ok", "B").

sapply, on the other hand, replaces everything with NAs.

Something else I've tried is this:

dat$value <- dat$choice

for(i in 1:length(dat_nat_last$choice)){
if(dat$value [i] == dat$choice[i]) {
dat$value [i] = "ok"
else {
dat$value [i] = "no"

Which returns the error "Error in dat$value[i] == dat[i] : comparison of these types is not implemented"

Any suggestion?

Answer Source

If the character strings "no"and "ok" are required instead of logical values FALSE and TRUE, there is a nice alternative to ifelse() using factor() with the appropriate factor labels:

dat$value <- factor(dat$position == dat$choice, labels = c("no", "ok"))
  position choice value
1        A      A    ok
2        B      A    no
3        B      B    ok
4        A      B    no
5        B      A    no
6        A      B    no
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download