IT story

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

hot-time 2020. 6. 13. 09:45
반응형

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

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


Another option is to use summary function. It gives a summary of the Ts, Fs and NAs.

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

I've been doing something similar a few weeks ago. Here's a possible solution, it's written from scratch, so it's kind of beta-release or something like that. I'll try to improve it by removing loops from code...

The main idea is to write a function that will take 2 (or 3) arguments. First one is a data.frame which holds the data gathered from questionnaire, and the second one is a numeric vector with correct answers (this is only applicable for single choice questionnaire). Alternatively, you can add third argument that will return numeric vector with final score, or data.frame with embedded score.

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

I'll try to do this in a more elegant manner with some *ply function. Notice that I didn't put na.rm argument... Will do that

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

Now apply a function:

> fscore(d, sol)
 [1] 6 4 2 4 4 3 3 6 2 6

If you pass data.frame argument, it will return modified data.frame. I'll try to fix this one... Hope it helps!


I've just had a particular problem where I had to count the number of true statements from a logical vector and this worked best for me...

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

So This takes a subset of the gene.rep.matrix object, and applies a logical test, returning a logical vector. This vector is put as an argument to grep, which returns the locations of any TRUE entries. Length then calculates how many entries grep finds, thus giving the number of TRUE entries.

참고URL : https://stackoverflow.com/questions/2190756/how-to-count-true-values-in-a-logical-vector

반응형