如何编写具有条件查找功能的顺序for循环

时间:2019-04-09 15:01:18

标签: r function for-loop

初学者在这里。 我正在尝试编写一个for循环来调整分数。 for循环的第一部分创建一个条件输出,该条件输出应传递到具有查找功能的for循环的第二部分。

在第一个data.frame中,a有2列

  • 得分(参与者得分)
  • 问题(与参与者得分有关的问题)

在第二个data.frame b中,有5列

  • 得分(参与者得分)
  • q(问题= 1时的调整分数)
  • r(问题= 2时的调整分数)
  • s(问题= 0时的调整分数)
  • t(问题> 2时的调整分数)

在第一个for循环中,我找到了索引 a $ score = b $ score

然后在第二个循环中,将索引传递给另一个循环。 根据a $ problem中的值,循环将以(q,r,s,t)返回正确的调整值。

这是data.frame a

id      score   problem
1       11      1
2       12      6
3       13      2
4       14      0
5       NA      NA

这是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

我希望函数的输出为a,a $ adjusted

中的新列。

这是我一直在尝试的功能,

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))
    }
  }
  }

这对我来说仍然是新的。 不知道我要去哪里错了。 当我分配时:

a$adjusted <- adjust(a$problem, a$score)

什么都没发生

任何人和所有人的帮助在这里都非常感谢。

1 个答案:

答案 0 :(得分:0)

为了简化嵌套的ifelse语句,我使用了dplyr软件包中的case_when函数。我还使用了match函数来简化内部循环(即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]]} )