这是我的示例数据集
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)
有快速/有效的方法吗?
答案 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