Moje przykładowe dane wygląda tak:

df <- data.frame(a = c(".", "X", ".", "Y", "."),
                  b = c(".", ".", ".", ".", "."),
                  c = c("A", ".", "Y", "X", "T"), stringsAsFactors = FALSE)

Próbuję policzyć liczbę znaków, które nie pasują do "." lub "X" dla każdej kolumny ramki danych. Są to jedyne dwie postacie, które próbuję zignorować. Próbowałem:

counts <- apply(df, 2, function(x) sum(x != "." | x != "X"))

To daje:

> counts
a b c 
5 5 5 

Zamiast tego spodziewałem się:

a b c
1 0 3

Czy ktoś może doradzić?

r
1
viralrna 17 kwiecień 2021, 01:17

2 odpowiedzi

Najlepsza odpowiedź

Powinien być operacja & zamiast |, ponieważ | zwraca TRUE w 3 przypadkach (TRUE|TRUE, TRUE|FALSE FALSE|TRUE). Jako pierwszy wyrażenie df != "." zwraca się do wszystkich elementów innych niż . i drugi true dla elementów innych niż "x", {x8}} zwraca pełną liczbę, tj. Łączna liczba wierszy jako prawda .

Może być bardziej wydajny z colSums

colSums(df != "."& df != "X")
#a b c 
#1 0 3 

Lub używając kodu OP

apply(df, 2, function(x) sum(x  != "." & x != "X"))
#a b c 
#1 0 3 

Lub jeśli jest więcej elementów, użyj %in% i neguj (!), aby zmienić prawdziwe - & gt; False i false - & gt; PRAWDZIWE

apply(df, 2, function(x) sum(! x %in% c(".", "X")))
# a b c 
#1 0 3 
3
akrun 16 kwiecień 2021, 22:25

Myślę, że to rozwiązanie może cię interesować:

library(dplyr)
library(stringr)

df %>%
  summarise(across(a:c, ~ sum(str_detect(., "\\.|X", negate = TRUE)))) 

  a b c
1 1 0 3

3
Anoushiravan R 16 kwiecień 2021, 23:12