[r] 논리 형 벡터에서 TRUE 값을 계산하는 방법

R TRUE에서 논리 벡터 의 값 수를 계산하는 가장 효율적인 / 아이디 오마 틱 방법은 무엇입니까? 두 가지 방법을 생각할 수 있습니다.

z <- sample(c(TRUE, FALSE), 1000, rep = TRUE)
sum(z)
# [1] 498

table(z)["TRUE"]
# TRUE 
#  498 

당신은 어느 것을 선호합니까? 더 좋은 것이 있습니까?



답변

논리 형 벡터에 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.


답변

언급되지 않은 또 다른 옵션은 다음을 사용하는 것입니다 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경우 가장 좋은 방법은 명확하게 사용하는 것 입니다. NAMarek이 제안한대로 값 을 확인할 수도 있습니다 .

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하므로 비논리적 값은 기본적으로 무시합니다.


답변

다른 방법은

> length(z[z==TRUE])
[1] 498

동안은 sum(z) 나를 위해, 좋은 짧은 length(z[z==TRUE])설명 자급입니다. 그러나 나는 이와 같은 간단한 작업으로 실제로 차이를 만들지 않는다고 생각합니다 …

그것이 큰 벡터라면 아마도 가장 빠른 해결책을 사용해야 할 것입니다 sum(z). length(z[z==TRUE])약 10x 느리고 table(z)[TRUE]약 200x 느립니다 sum(z).

요약 sum(z)하면 입력하고 실행하는 것이 가장 빠릅니다.


답변

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 = TRUEsum기능, 당신은 당신이 원하는 결과를 얻을 수 있습니다.

> sum(x)
[1] NA
> sum(x, na.rm=TRUE)
[1] 43

질문이 엄격하게 이론적인가, 논리 벡터에 관한 실제적인 문제가 있습니까?


답변

또 다른 옵션은 요약 기능을 사용하는 것입니다. 그것은 Ts, Fs 및 NA의 요약을 제공합니다.

> summary(hival)
   Mode   FALSE    TRUE    NA's
logical    4367      53    2076
> 


답변

몇 주 전에 비슷한 일을 해왔습니다. 여기에 가능한 해결책이 있습니다. 처음부터 작성되었으므로 일종의 베타 릴리스 또는 이와 유사한 것입니다. 코드에서 루프를 제거하여 개선하려고 노력할 것입니다 …

주요 아이디어는 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이 반환됩니다. 이 문제를 해결하려고 노력하겠습니다 … 도움이 되길 바랍니다.


답변

나는 논리적 인 벡터에서 진정한 진술의 수를 세어야 할 특별한 문제가 있었는데 이것은 나에게 가장 효과적이었다 …

length(grep(TRUE, (gene.rep.matrix[i,1:6] > 1))) > 5

따라서 이것은 gene.rep.matrix 객체의 하위 집합을 가져 와서 논리 테스트를 적용하여 논리 벡터를 반환합니다. 이 벡터는 grep의 인수로 사용되며 TRUE 항목의 위치를 ​​반환합니다. 그러면 Length는 grep이 찾은 항목 수를 계산하여 TRUE 항목 수를 제공합니다.