R: Использование различных подэлементов (определенных строк каждого столбца) с sapply - PullRequest
0 голосов
/ 11 марта 2019

У меня есть data.frame с идентификаторами клиентов и различными комбинациями трех переменных.Моим первым шагом было найти наиболее распространенные комбинации, что достигается с помощью следующего кода.

possible_s = c("a","b","c","d","e")
n = 10000
df = tibble(customer_id = sample(1:10000,n,replace = T ),
                s1 = sample(possible_s,n,replace = T ),
                s2 = sample(possible_s,n,replace = T ),
                s3 = sample(possible_s,n,replace = T ))


combinations = table(apply(df[,2:4], 1, function(x) paste0(sort(x), collapse = ""))) %>% 
  as_tibble() %>% 
  arrange(desc(n))

combinations = combinations %>% 
  mutate(
    s1 = sapply(combinations[ ,1],function(x) substr(x,1,1)),
    s2 = sapply(combinations[ ,1],function(x) substr(x,2,2)),
    s3 = sapply(combinations[ ,1],function(x) substr(x,3,3))
  ) 

Теперь я хочу вывести идентификаторы для наиболее 20 наиболее распространенных комбинаций.Это решение сделать это вручную для первой комбинации:

combinations[1, ]
# A tibble: 1 x 5
  Var1      n s1    s2    s3   
  <chr> <int> <chr> <chr> <chr>
1 cde     503 c     d     e 

df %>%
  mutate(count_c = rowSums(apply(df,2,function(x) str_count(x, 'c')) )) %>% 
  mutate(count_d = rowSums(apply(df,2,function(x) str_count(x, 'd')) )) %>% 
  mutate(count_e = rowSums(apply(df,2,function(x) str_count(x, 'e')) )) %>% 
  filter(count_c == 1,count_d == 1,count_e == 1) %>% 
  distinct(customer_id)

Моя попытка сделать это для первых 20 комбинаций следующая:

sapply( as.data.frame ( t( combinations[1:20,3:5]),stringsAsFactors = F )  ,function(y) 
  df %>%
    mutate(vfg1 = rowSums(apply(df,2,function(x) str_count(x,y[1])) )) %>% 
    mutate(vfg2 = rowSums(apply(df,2,function(x) str_count(x,y[2])) )) %>%
    mutate(vfg3 = rowSums(apply(df,2,function(x) str_count(x,y[3])) )) 
) %>%
  filter(vfg1 == 1,vfg2 == 1,vfg3 == 1) %>% 
  distinct(VERSICHERTER_BP_ID)

К сожалению, это не даетмне желаемый результат.Чтобы связать разные идентификаторы вместе, я придумал что-то вроде этого:

do.call("bind",sapply( as.data.frame ( t( combinations[1:10,3:5]),stringsAsFactors = F )  ,function(y) 
  df %>%
    mutate(vfg1 = rowSums(apply(df,2,function(x) str_count(x,y[1])) )) %>% 
    mutate(vfg2 = rowSums(apply(df,2,function(x) str_count(x,y[2])) )) %>%
    mutate(vfg3 = rowSums(apply(df,2,function(x) str_count(x,y[3])) )) 
) %>%
  filter(vfg1 == 1,vfg2 == 1,vfg3 == 1) %>% 
  distinct(VERSICHERTER_BP_ID))

Помимо сохранения всех идентификаторов из 20 первых комбинаций в одной таблице, я также хочу сохранить идентификаторы каждой комбинации в списке, гдекаждая комбинация и соответствующие идентификаторы являются одним из элементов списка.

1 Ответ

0 голосов
/ 12 марта 2019

Хотя это может быть не самый эффективный способ сделать это.Это решение, которое работает:

top20_combinations = combinations %>% slice(1:20) %>% select(3:5)
customer_ids = vector("list", length = nrow(top20_combinations))
for (i in 1:nrow(top20_combinations)) {
  df2 = df %>%
    mutate(vfg1 = rowSums(apply(df,2,function(x) str_count(x, top20_combinations[[i,1]] )) )) %>% 
    mutate(vfg2 = rowSums(apply(df,2,function(x) str_count(x, top20_combinations[[i,2]] )) )) %>%
    mutate(vfg3 = rowSums(apply(df,2,function(x) str_count(x, top20_combinations[[i,3]] )) )) %>%
    filter(vfg1 == 1,vfg2 == 1,vfg3 == 1) %>% 
    distinct(customer_id )
   customer_ids[[i]] = df2$customer_id
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...