답변:
논리 형 벡터에 NA
값이 포함 된 경우 몇 가지 문제가 있습니다.
예를 들어 :
z <- c(TRUE, FALSE, NA)
sum(z) # gives you NA
table(z)["TRUE"] # gives you 1
length(z[z == TRUE]) # f3lix answer, gives you 2 (because NA indexing returns values)
가장 안전한 방법은 다음과 na.rm = TRUE
같습니다.
sum(z, na.rm = TRUE) # best way to count TRUE values
(1을 제공합니다). 나는 table
해결책이 덜 효율적 이라고 생각합니다 ( table
함수 코드를보십시오 ).
또한 논리 벡터에 TRUE 값이없는 경우 "테이블"솔루션에주의해야합니다. 가정 z <- c(NA, FALSE, NA)
하거나 간단하게 두 경우 모두 z <- c(FALSE, FALSE)
를 table(z)["TRUE"]
제공합니다 NA
.
sum(z, na.rm = TRUE)
언급되지 않은 또 다른 옵션은 다음을 사용하는 것입니다 which
.
length(which(z))
실제로 "더 빠른 질문"에 대한 컨텍스트를 제공하기 위해 항상 스스로 테스트하는 것이 가장 쉽습니다. 비교를 위해 벡터를 훨씬 더 크게 만들었습니다.
z <- sample(c(TRUE,FALSE),1000000,rep=TRUE)
system.time(sum(z))
user system elapsed
0.03 0.00 0.03
system.time(length(z[z==TRUE]))
user system elapsed
0.75 0.07 0.83
system.time(length(which(z)))
user system elapsed
1.34 0.28 1.64
system.time(table(z)["TRUE"])
user system elapsed
10.62 0.52 11.19
따라서이 sum
경우 가장 좋은 방법은 명확하게 사용하는 것 입니다. NA
Marek이 제안한대로 값 을 확인할 수도 있습니다 .
NA 값과 which
함수 에 관한 메모를 추가하려면 다음을 수행하십시오.
> which(c(T, F, NA, NULL, T, F))
[1] 1 4
> which(!c(T, F, NA, NULL, T, F))
[1] 2 5
이는 logical 만 검사 TRUE
하므로 비논리적 값은 기본적으로 무시합니다.
which
특히 행렬을 조작 할 때 좋은 대안입니다 ( 인자를 확인 ?which
하고 확인하십시오 arr.ind
). 그러나 논리 벡터에서 처리 할 수 sum
있는 na.rm
인수 때문에을 고수하는 것이 좋습니다 NA
. 예를 들어 :
# create dummy variable
set.seed(100)
x <- round(runif(100, 0, 1))
x <- x == 1
# create NA's
x[seq(1, length(x), 7)] <- NA
당신이 입력하면 sum(x)
당신이 얻을 것이다 NA
결과로, 그러나 당신이 전달하는 경우 na.rm = TRUE
에 sum
기능, 당신은 당신이 원하는 결과를 얻을 수 있습니다.
> sum(x)
[1] NA
> sum(x, na.rm=TRUE)
[1] 43
질문이 엄격하게 이론적인가, 논리 벡터에 관한 실제적인 문제가 있습니까?
몇 주 전에 비슷한 일을 해왔습니다. 여기에 가능한 해결책이 있습니다. 처음부터 작성되었으므로 일종의 베타 릴리스 또는 이와 유사한 것입니다. 코드에서 루프를 제거하여 개선하려고 노력할 것입니다 ...
주요 아이디어는 2 또는 3 개의 인수를 취하는 함수를 작성하는 것입니다. 첫 번째는 data.frame
설문지에서 수집 한 데이터를 보유하고 있고 두 번째는 정답이있는 숫자 형 벡터입니다 (단일 선택 설문에만 적용 가능). 또는 최종 점수가 포함 된 숫자 형 벡터 또는 점수가 포함 된 data.frame을 반환하는 세 번째 인수를 추가 할 수 있습니다.
fscore <- function(x, sol, output = 'numeric') {
if (ncol(x) != length(sol)) {
stop('Number of items differs from length of correct answers!')
} else {
inc <- matrix(ncol=ncol(x), nrow=nrow(x))
for (i in 1:ncol(x)) {
inc[,i] <- x[,i] == sol[i]
}
if (output == 'numeric') {
res <- rowSums(inc)
} else if (output == 'data.frame') {
res <- data.frame(x, result = rowSums(inc))
} else {
stop('Type not supported!')
}
}
return(res)
}
나는 * 플라이 기능을 사용하여보다 우아한 방식 으로이 작업을 시도합니다. 내가 na.rm
논쟁을 하지 않았다는 것에 주목 하라.
# create dummy data frame - values from 1 to 5
set.seed(100)
d <- as.data.frame(matrix(round(runif(200,1,5)), 10))
# create solution vector
sol <- round(runif(20, 1, 5))
이제 함수를 적용하십시오.
> fscore(d, sol)
[1] 6 4 2 4 4 3 3 6 2 6
data.frame 인수를 전달하면 수정 된 data.frame이 반환됩니다. 이 문제를 해결하려고 노력하겠습니다 ... 도움이 되길 바랍니다.
rowSums(t(t(d)==sol), na.rm=TRUE)
. 비교를위한 R 재순환 벡터. 당신이 경우 d
다음 열에있는 경우에 그것의 단순화와 매트릭스했다 rowSums(d==sol, na.rm=TRUE)
.
나는 논리적 인 벡터에서 진정한 진술의 수를 세어야 할 특별한 문제가 있었는데 이것은 나에게 가장 효과적이었다 ...
length(grep(TRUE, (gene.rep.matrix[i,1:6] > 1))) > 5
따라서 이것은 gene.rep.matrix 객체의 하위 집합을 가져 와서 논리 테스트를 적용하여 논리 벡터를 반환합니다. 이 벡터는 grep의 인수로 사용되며 TRUE 항목의 위치를 반환합니다. 그러면 Length는 grep이 찾은 항목 수를 계산하여 TRUE 항목 수를 제공합니다.
table(c(FALSE))["TRUE"]
NA, 0이 아닌 수 있습니다