Считать вхождения факторов, разделенных запятыми, И условных? в R - PullRequest
1 голос
/ 10 апреля 2020

Я пытаюсь выполнить некоторые сложные вычисления, и часть кода требует, чтобы я проанализировал разделенную запятыми запись и посчитал количество значений, превышающих 0.

Пример входных данных:

a <- c(0,0,3,0)
b <- c(4,4,0,1)
c <- c("3,4,3", "2,1", 0, "5,8")
x <- data.frame(a, b, c)

x

  a b     c
1 0 4 3,4,3
2 0 4   2,1
3 3 0     0
4 0 1   5,8

Столбец, который мне нужно проанализировать, c - это факторы, а все остальные столбцы - цифры c. Число значений, разделенных запятой, будет варьироваться, в этом примере оно варьируется от 0 до 3. Требуемый результат будет выглядеть следующим образом :

x$c_occur <- c(3, 2, 0, 2)
x

  a b     c c_occur
1 0 4 3,4,3       3
2 0 4   2,1       2
3 3 0     0       0
4 0 1   5,8       2

Где c_occur указывает число вхождения> 0 в столбце c.

Я думал, что-то вроде этого будет работать ... но я не могу понять это.

library(dplyr
 x_desired <- x %>%
   mutate(c_occur = count(strsplit(c, ","), > 0))

1 Ответ

1 голос
/ 10 апреля 2020

Мы можем использовать str_count

library(stringr)
library(dplyr)
x %>%
    mutate(c_occur = str_count(c, '[1-9]\\d*'))
#  a b     c c_occur
#1 0 4 3,4,3       3
#2 0 4   2,1       2
#3 3 0     0       0
#4 0 1   5,8       2

После разбиения 'c' мы можем получить счет, sum используя логический вектор после цикла по list вывод из strsplit

library(purrr)    
x %>%
   mutate(c_occur =  map_int(strsplit(as.character(c), ","),
       ~ sum(as.integer(.x) > 0)))
# a b     c c_occur
#1 0 4 3,4,3       3
#2 0 4   2,1       2
#3 3 0     0       0
#4 0 1   5,8       2

Или мы можем разделить строки с помощью separate_rows и сделать group_by summarise

library(tidyr)    
x %>%
     mutate(rn = row_number()) %>% 
     separate_rows(c, convert = TRUE) %>%
     group_by(rn) %>%
     summarise(c_occur = sum(c >0)) %>%
     select(-rn) %>% 
     bind_cols(x, .)
# A tibble: 4 x 4
#      a     b c     c_occur
#  <dbl> <dbl> <fct>   <int>
#1     0     4 3,4,3       3
#2     0     4 2,1         2
#3     3     0 0           0
#4     0     1 5,8         2
...