Разверните фрейм данных по идентификатору, чтобы создать специальный столбец - PullRequest
1 голос
/ 19 марта 2019

У меня есть следующий фрейм данных

  df<-data.frame("ID"=c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), 
           'A_Frequency'=c(1,2,3,4,5,1,2,3,4,5), 
  'B_Frequency'=c(1,2,NA,4,6,1,2,5,6,7))

Фрейм данных выглядит следующим образом

   ID A_Frequency B_Frequency
1   A           1           1
2   A           2           2
3   A           3           NA
4   A           4           4
5   A           5           6
6   B           1           1
7   B           2           2
8   B           3           5
9   B           4           6
10  B           5           7

Хочу создать новый фрейм данных df2 из df, который выглядит следующим образом

     ID CFreq
 1   A     1
 2   A     2
 3   A     3
 4   A     4
 5   A     5
 6   A     6
 7   B     1
 8   B     2
 9   B     3
10  B     4
11  B     5
12  B     6
13  B     7

Новый фрейм данных имеет столбец CFreq, который принимает уникальные значения из A_Frequency, B_Frequency и группирует их по ID. Затем он игнорирует значения NA и генерирует столбец CFreq

Я пробовал dplyr, но не могу получить требуемый ответ

  df2<-df%>%group_by(ID)%>%select(ID, A_Frequency,B_Frequency)%>%
  mutate(Cfreq=unique(A_Frequency, B_Frequency)) 

Это дает следующее, что совсем другое

   ID    A_Frequency B_Frequency Cfreq
  <fct>       <dbl>       <dbl> <dbl>
 1 A               1           1     1
 2 A               2           2     2
 3 A               3          NA     3
 4 A               4           4     4
 5 A               5           6     5
 6 B               1           1     1
 7 B               2           2     2
 8 B               3           5     3
 9 B               4           6     4
 10 B               5           7     5

Попросите кого-нибудь помочь мне здесь

Ответы [ 4 ]

2 голосов
/ 19 марта 2019

Другая tidyverse возможность может быть:

df %>%
 nest(A_Frequency, B_Frequency, .key = C_Frequency) %>%
 mutate(C_Frequency = map(C_Frequency, function(x) unique(x[!is.na(x)]))) %>%
 unnest()

   ID C_Frequency
1   A           1
2   A           2
3   A           3
4   A           4
5   A           5
9   A           6
10  B           1
11  B           2
12  B           3
13  B           4
14  B           5
18  B           6
19  B           7
2 голосов
/ 19 марта 2019

gather функция из tidyr пакета будет полезна здесь:

library(tidyverse)

df %>%
  gather(x, CFreq, -ID) %>%
  select(-x) %>%
  na.omit() %>%
  unique() %>%
  arrange(ID, CFreq)
1 голос
/ 19 марта 2019

Подход Base R заключается в split кадре данных, основанном на ID, и для каждого списка мы подсчитываем количество уникальных записей и создаем последовательность на основе этого.

do.call(rbind, lapply(split(df, df$ID), function(x) data.frame(ID = x$ID[1] , 
        CFreq = seq_len(length(unique(na.omit(unlist(x[-1]))))))))


#    ID CFreq
#A.1  A     1
#A.2  A     2
#A.3  A     3
#A.4  A     4
#A.5  A     5
#A.6  A     6
#B.1  B     1
#B.2  B     2
#B.3  B     3
#B.4  B     4
#B.5  B     5
#B.6  B     6
#B.7  B     7

Это также будет работать, когда A_Frequency B_Frequency содержит символы или некоторые другие случайные числа вместо последовательных чисел.


В tidyverse мы можем сделать

library(tidyverse)

df %>%
  group_split(ID) %>%
  map_dfr(~ data.frame(ID = .$ID[1], 
  CFreq= seq_len(length(unique(na.omit(flatten_chr(.[-1])))))))
0 голосов
/ 19 марта 2019

A data.table опция

library(data.table)
cols <- c('A_Frequency', 'B_Frequency')
out <- setDT(df)[, .(CFreq = sort(unique(unlist(.SD)))),
                 .SDcols = cols,
                 by = ID]
out
#    ID CFreq
# 1:  A     1
# 2:  A     2
# 3:  A     3
# 4:  A     4
# 5:  A     5
# 6:  A     6
# 7:  B     1
# 8:  B     2
# 9:  B     3
#10:  B     4
#11:  B     5
#12:  B     6
#13:  B     7
...