Подсчет уникальных значений по столбцам в R - PullRequest
1 голос
/ 12 апреля 2019

Я пытаюсь создать новую переменную с уникальным количеством строковых значений из двух разных столбцов. Итак, у меня есть что-то вроде этого, например:

# A tibble: 4 x 2
  names   partners                 
  <fct>   <fct>                    
1 John    Mary, Ashley, John, Kate 
2 Mary    Charlie, John, Mary, John
3 Charlie Kate, Marcy              
4 David   Mary, Claire 
structure(list(names = structure(c(3L, 4L, 1L, 2L), .Label = c("Charlie", 
"David", "John", "Mary"), class = "factor"), partners = structure(c(3L, 
1L, 2L, 4L), .Label = c("Charlie, John, Mary, John", "Kate, Marcy", 
"Mary, Ashley, John, Kate", "Mary, Claire"), class = "factor")), row.names = c(NA, 
4L), class = "data.frame")

и я хочу получить что-то вроде этого

# A tibble: 4 x 3
  names   partners                  uniquecounts
  <fct>   <fct>                            <dbl>
1 John    Mary, Ashley, John, Kate             4
2 Mary    Charlie, John, Mary, John            3
3 Charlie Kate, Marcy                          3
4 David   Mary, Claire                         3

Я попытался объединить оба столбца в одном и подсчитать в нем уникальные значения, но это не сработало.

Ответы [ 3 ]

2 голосов
/ 12 апреля 2019

С помощью tidyverse сначала преобразуйте столбцы фактора в символ, используйте map2 и разбейте partners на отдельный вектор строк, а затем подсчитайте уникальные значения, объединенные с names, используя n_distinct.

library(tidyverse)

df %>%
  mutate_all(as.character) %>%
  mutate(uniquecounts = map2_dbl(names, partners, 
                       ~ n_distinct(c(.x, str_split(.y, ", ")[[1]]))))


#    names                    partners uniquecounts
#1    John  Mary, Ashley, John, Kate            4
#2    Mary Charlie, John, Mary, John            3
#3 Charlie               Kate, Marcy            3
#4   David              Mary, Claire            3

С той же логикой в ​​базе R

df[] <- lapply(df, as.character)
as.numeric(mapply(function(x, y) length(unique(c(x, y))), 
          df$names, strsplit(df$partners, ", ")))
#[1] 4 3 3 3
0 голосов
/ 12 апреля 2019

Вот метод, использующий tidyverse без зацикливания

library(tidyverse)
df1 %>% 
   mutate(partners = str_c(names, partners, sep=", ")) %>%
   separate_rows(partners) %>%
   distinct %>% 
   count(names) %>% 
   right_join(df1)
# A tibble: 4 x 3
#  names       n partners                 
#  <fct>   <int> <fct>                    
#1 John        4 Mary, Ashley, John, Kate 
#2 Mary        3 Charlie, John, Mary, John
#3 Charlie     3 Kate, Marcy              
#4 David       3 Mary, Claire         
0 голосов
/ 12 апреля 2019

Есть еще один способ с toString.

dat$uniquecounts <- sapply(strsplit(apply(dat, 1, toString), ", "), 
                           function(x) length(unique(x)))

dat
#     names                  partners uniquecounts
# 1    John  Mary, Ashley, John, Kate            4
# 2    Mary Charlie, John, Mary, John            3
# 3 Charlie               Kate, Marcy            3
# 4   David              Mary, Claire            3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...