计算r中不正确值的频率

时间:2013-09-16 16:02:31

标签: r loops if-statement

这是我的示例数据集

 set.seed(123)
 myd <- data.frame (sub = paste ("S", 1:10, sep = ""), P1 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    P2 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    I1 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    I2 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    I3 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    I4 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    I5 = sample(c(1,-1,2,0), 10, replace = TRUE),
                    I6 = sample(c(1,-1,2,0), 10, replace = TRUE)
                    )
 myd 

  sub P1 P2 I1 I2 I3 I4 I5 I6
1   S1 -1  0  0  0  1  1  2  0
2   S2  0 -1  2  0 -1 -1  1  2
3   S3 -1  2  2  2 -1  0 -1  2
4   S4  0  2  0  0 -1  1 -1  1
5   S5  0  1  2  1  1  2  0 -1
6   S6  1  0  2 -1  1  1 -1  1
7   S7  2  1  2  0  1  1  0 -1
8   S8  0  1  2  1 -1  0  0  2
9   S9  2 -1 -1 -1 -1  0  0 -1
10 S10 -1  0  1  1  0 -1 -1  1

以值P1和P2为条件的错误值的转换表: -1缺少值

  Condition   P1    P2         The value Incorrect
    I         1     1           None
    II        1     0           2
    III       0     1           2
     IV       2     0           2 or 0
      V       0     2          2 or 0
      VI      2     2          1 or 0
      VII     1     2          0
     VIII     2     1          0

 # if there is -1 in any of the value produce all values NA
      IX      -1      0           NA
      X        0     -1           NA
      XI      -1     -1           NA
      XII      -1     2           NA
       XIII     2    -1           NA
      XIV      -1     1           NA
      XV        1     -1           NA

以下是data.frame格式的转换表的简短代码,除了** ,对于我不知道如何输入的IV,V,VI条件,因为有两个值:

 ttable <- data.frame (P1 = c(1,1,0,2,0,2,1,2,-1, 0,-1,-1,2,-1,1), 
                     P2 = c(1,0,1,0,2,2,2,1,0,-1,-1,2,-1,1,1), 
                   errort = c("None", 2,2,2, 2,1,0,0,NA, NA, NA, NA, NA, NA,NA))

我想查看每个s1到s10行的内容,我想检查P1和P2列中的值,并将其与I1到I6列中的值匹配:

   sub   P1 P2 I1 I2 I3 I4 I5 I6
1   S1   -1  0  0  0  1  1  2  0

在这种情况下,P1和P2中的一个值为-1,因此所有值都将为NA。

另一个案例:

          sub   P1 P2  I1  I2  I3  I4   I5  I6
           S4   0  2   0   0  -1   1   -1   1

这里P1 = 0,P2 = 2,所以以下值 I1 =不正确,I2 =不正确,I3 = NA,I4 =正确,I5 = NA,I6 =正确

可以写成

sub   P1 P2  I1      I2     I3   I4     I5   I6
 S4   0  2   0      0      -1    1     -1    1

            FALSE, FALSE,  NA,  TRUE, NA,  TRUE 

与条件(V)和0或1的匹配不正确,而1正确且缺少-1

另一种情况:此处P1 = 0且P2 = 1,与匹配表中的条件(III)匹配,因此不正确的值将为2.

 5   S5  0  1   2      1     1     2      0      -1
               FALSE, TRUE,  TRUE  FALSE  TRUE    NA

我需要计算错误的频率,我尝试了很多if-else语句但没有给出所需的输出,我觉得有很多这样的messey,我认为这对我将使用的大型数据集没有效率。

qcfun <- function (x) {
x <- x[3:length(x)]
obs1 =   table(c(x, 2, 0, 1, -1))
obs = obs1-1
ov <- NULL
if (x[1] == 1 & x[2] == 0){
ov = round (as.numeric (obs[4]/sum(obs)), 2)
} else {
if (x[1] == 0 & x[2] == 1){
ov = round (as.numeric (obs[4]/sum(obs)), 2)
} else {
if (x[1] == 1 & x[2] == 2){
ov = round (as.numeric (obs[2]/sum(obs)), 2)
} else {
if (x[1] == 2 & x[2] == 1){
ov = round (as.numeric (obs[2]/sum(obs)), 2)
} else {
if (x[1] == 1 & x[2] == 1){
ov = 0
} else {
ov = NA
}
}}}}
return (ov)
}
out1 <- apply(myd, 1,qcfun )
table (out1)
tout1 <- table (out1)

有快速/有效的方法吗?

1 个答案:

答案 0 :(得分:2)

您可以使用此向量化函数,它对大量行有效:

fixI <- function(p1, p2, i){
    negative <- (p1 < 0) | (p2 < 0) | (i < 0)
    result <- ifelse(negative, NA, TRUE)  # conditions IX to XV

    p <- p1 * 10 + p2

    result[!negative & p %in% c(10,1,20,2) & i==2] <- FALSE
    result[!negative & p %in% c(20,2,22,12,21) & i==0] <- FALSE
    result[!negative & p==22 & i==1] <- FALSE

    result
}

将其应用于I中的myd列:

mat <- sapply(myd[,paste0("I",1:6)], fixI, p1=myd$P1, p2=myd$P2)

rownames(mat) <- myd$sub

结果:

       I1    I2   I3    I4    I5    I6
S1     NA    NA   NA    NA    NA    NA
S2     NA    NA   NA    NA    NA    NA
S3     NA    NA   NA    NA    NA    NA
S4  FALSE FALSE   NA  TRUE    NA  TRUE
S5  FALSE  TRUE TRUE FALSE  TRUE    NA
S6  FALSE    NA TRUE  TRUE    NA  TRUE
S7   TRUE FALSE TRUE  TRUE FALSE    NA
S8  FALSE  TRUE   NA  TRUE  TRUE FALSE
S9     NA    NA   NA    NA    NA    NA
S10    NA    NA   NA    NA    NA    NA

现在你可以像这样算FALSE

按行:

apply(!mat, 1, sum, na.rm=TRUE)

 S1  S2  S3  S4  S5  S6  S7  S8  S9 S10 
  0   0   0   2   2   1   2   2   0   0 

按栏:

apply(!mat, 2, sum, na.rm=TRUE)

 I1 I2 I3 I4 I5 I6 
  4  2  0  1  1  1