Использование dplyr и mutate с отдельными условиями для каждого из нескольких столбцов - PullRequest
0 голосов
/ 09 ноября 2018

Я пытаюсь подсчитать количество уникальных символов в нескольких столбцах (t1, t2, t3) и поместить это значение в новую переменную. То, считается ли символ, зависит от значения другого столбца, с которым он связан (p1, p2, p3), больше или равного 0,05. Например. У меня есть следующий набор данных:

dat <- data.frame(id = c(1,2,3,4,5),t1 = c('a','a','b','b','c'),
            p1 = c(0.98,1,0.5,0.9,1),t2 = c('b',NA,'a','c',NA),
            p2 = c(0.02,NA,0.25,0.10,NA), t3 = c(NA,NA,'c',NA,NA),
            p3 = c(NA,NA,0.25,NA,NA))

Я рассчитываю подсчитать количество уникальных значений, присутствующих в столбцах t1, t2, t3 для данной строки, и поместить это число в новую переменную (total), которая должна иметь вывод, подобный так:

output <- data.frame(id = c(1,2,3,4,5),t1 = c('a','a','b','b','c'),
            p1 = c(0.98,1,0.5,0.9,1),t2 = c('b',NA,'a','c',NA),
            p2 = c(0.02,NA,0.25,0.10,NA), t3 = c(NA,NA,'c',NA,NA),
            p3 = c(NA,NA,0.25,NA,NA), total = c(1,1,3,2,1))

Используя dplyr, я могу считать уникальные символы в t1, t2 и t3 с помощью этого кода:

output <- dat %>%
 group_by(id) %>%
 mutate(total = n_distinct(c(t1,t2,t3), na.rm = TRUE))

Однако я не могу установить условия, при которых p1, p2 и p3 должны быть> = 0,05, если t1, t2 или t3, соответственно, будут учитываться для достижения желаемого результата. Есть ли способ установить это условие для каждого столбца t1, t2, t3? Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Использование tidyverse:

dat %>%
  mutate(t1 = ifelse(p1 >= 0.05, paste(t1), NA), #Applying the condition
         t2 = ifelse(p2 >= 0.05, paste(t2), NA),
         t3 = ifelse(p3 >= 0.05, paste(t3), NA)) %>%
  select(t1, t2, t3, id) %>%
  gather(var, val, -id) %>% #Transforming data from wide to long format
  group_by(id) %>% #Grouping by ID
  mutate(total = n_distinct(val, na.rm = TRUE)) %>% #Calculating the number of unique values
  spread(var, val) %>% #Transforming the data back to wide format
  select(id, total) %>% 
  left_join(dat, by = c("id" = "id"), copy = FALSE) #Joining with the original data 

     id total t1       p1 t2         p2 t3        p3
  <dbl> <int> <fct> <dbl> <fct>   <dbl> <fct>  <dbl>
1    1.     1 a     0.980 b      0.0200 <NA>  NA    
2    2.     1 a     1.00  <NA>  NA      <NA>  NA    
3    3.     3 b     0.500 a      0.250  c      0.250
4    4.     2 b     0.900 c      0.100  <NA>  NA    
5    5.     1 c     1.00  <NA>  NA      <NA>  NA 

Или:

dat %>%
  group_by(id) %>%
  mutate(total = paste(t1[p1 >= 0.05], #Applying the condition
                       t2[p2 >= 0.05], 
                       t3[p3 >= 0.05]),
         total = sum(str_count(rawToChar(unique(charToRaw(total))), letters))) #Counting the number of unique characters

     id t1       p1 t2         p2 t3        p3 total
  <dbl> <fct> <dbl> <fct>   <dbl> <fct>  <dbl> <int>
1    1. a     0.980 b      0.0200 <NA>  NA         1
2    2. a     1.00  <NA>  NA      <NA>  NA         1
3    3. b     0.500 a      0.250  c      0.250     3
4    4. b     0.900 c      0.100  <NA>  NA         2
5    5. c     1.00  <NA>  NA      <NA>  NA         1

Общее количество уникальных персонажей:

dat %>%
  mutate(t1 = ifelse(p1 >= 0.05, paste(t1), NA), 
         t2 = ifelse(p2 >= 0.05, paste(t2), NA),
         t3 = ifelse(p3 >= 0.05, paste(t3), NA)) %>%
  select(t1, t2, t3, id) %>%
  gather(var, val, -id) %>% 
  mutate(overall = n_distinct(val, na.rm = TRUE)) %>% 
  spread(var, val) %>% 
  select(id, overall) %>% 
  left_join(dat, by = c("id" = "id"), copy = FALSE) 

  id overall t1   p1   t2   p2   t3   p3
1  1       3  a 0.98    b 0.02 <NA>   NA
2  2       3  a 1.00 <NA>   NA <NA>   NA
3  3       3  b 0.50    a 0.25    c 0.25
4  4       3  b 0.90    c 0.10 <NA>   NA
5  5       3  c 1.00 <NA>   NA <NA>   NA
0 голосов
/ 09 ноября 2018

Вы можете добавить условия и затем суммировать результаты.

dat %>% 
  group_by(id) %>% 
  mutate_if(is.factor,as.character) %>%  
  mutate(total = sum(p1>=.05*nchar(t1),p2>=.05*nchar(t2),p3>=.05*nchar(t3),na.rm = T))

# A tibble: 5 x 8
# Groups:   id [5]
#     id t1       p1 t2       p2 t3       p3 total
#  <dbl> <chr> <dbl> <chr> <dbl> <chr> <dbl> <int>
#1     1 a      0.98 b      0.02 NA    NA        1
#2     2 a      1    NA    NA    NA    NA        1
#3     3 b      0.5  a      0.25 c      0.25     3
#4     4 b      0.9  c      0.1  NA    NA        2
#5     5 c      1    NA    NA    NA    NA        1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...