Beginner here. I am trying to write a for loop to adjust a score. The first part of the for loop creates a conditional output which should be passed to the second part of the for loop which has a lookup function.
In the first data.frame, a, there are 2 columns
In the second data.frame, b, there are 5 columns
In the first for loop, I find the index where a$score = b$score
Then in the second loop, I pass the index to another loop. Based on the value in a$problem, the loop returns the correct adjusted value in (q, r, s, t).
Here is data.frame a
id score problem
1 11 1
2 12 6
3 13 2
4 14 0
5 NA NA
Here is data.frame b
score q r s t
11 12 13 11 NA
12 14 15 12 NA
13 16 20 13 NA
14 18 22 14 NA
NA NA NA NA NA
I would like the output of the function to be a new column in a, a$adjusted
Here is the function I have been trying,
adjust <- function (y, z){
# y = problem
# z = score
for(j in z){
index <- sapply(j, function(x) b$score %in% x)
for (i in y){
ifelse(i > 2,
z(i) <- b[index, 5],
ifelse(i == 2,
z(i) <- b[index, 3],
ifelse(i == 1,
z(i) <- b[index, 2],
ifelse( i == 0,
z(i) <- b[index, 4],
z(i) <- b[index, 5]))))
print(z(i))
}
}
}
This is still new for me. Not sure where I'm going wrong. When I assign:
a$adjusted <- adjust(a$problem, a$score)
Nothing happens
Any and all help very much appreciated here.
To simplify the nested ifelse statements I used the case_when
function from the dplyr package. I also used the match
function to simplify the inner loop (i.e. sapply)
a<-read.table(header=TRUE, text="id score problem
1 12 1
2 11 6
3 13 2
4 14 0
5 NA NA")
b<-read.table(header=TRUE, text="score q r s t
11 12 13 11 NA
12 14 15 12 NA
13 16 20 13 NA
14 18 22 14 NA
NA NA NA NA NA")
library(dplyr)
#find column name associated with problem score if NA use the score column
colname<-case_when(
a$problem==0 ~ "s",
a$problem==1 ~ "q",
a$problem==2 ~ "r",
a$problem >2 ~ "t",
is.na(a$problem) ~"score"
)
# find the corresponding row in table b to match data frame a
rowscore<-match(a$score, b$score)
#column name and rowscore are the same length
#loop through the column name/row name to find the adjusted score
a$adjusted<-sapply(1:length(rowscore), function(i){b[[colname[i]]][rowscore[i]]} )