2016-11-06 1 views
1

Я хотел бы создать новый фрейм данных на основе двух уникальных значений из другого фрейма данных.создать кадр данных на основе уникальных значений двух переменных в R

id <- c("A", "B", "B", "C") 
st.name <- c("TX", "TX", "CA", "CA") 
type <- c(21, 26, 29, 24) 
DF <- data.frame(id, st.name, type) 
print(DF) 

id st.name type 
A  TX 21 
B  TX 26 
B  CA 29 
C  CA 24 

Я хотел бы создать новый фрейм данных, основанный на уникальных значениях id и st.type. Результат будет выглядеть так:

new_id <- c("ATX", "ACA", "BTX", "BCA", "CTX", "CCA") 
new_type <- c(21, NA, 26, 29, NA, 24) 
DF2 <- data.frame(new_id, new_type) 
print(DF2) 

new_id new_type 
ATX  21 
ACA  NA 
BTX  26 
BCA  29 
CTX  NA 
CCA  24 

Я использовал dcast в предыдущих проектах, но я не уверен, как включить функцию здесь.

+0

Удивительно! спасибо @akrun – KMR

ответ

4

Мы можем сделать это с complete и unite от tidyr

library(tidyr) 
complete(DF, id, st.name) %>% 
       unite(new_id, id, st.name, sep = '') 

Или с помощью base R, мы можем получить ожидаемый результат с expand.grid, merge и paste

transform(merge(expand.grid(lapply(DF[1:2], unique)), 
      DF, all.x=TRUE), id = paste0(id, st.name))[-2] 

Или data.table вариант с CJ (упоминается @Frank в комментариях)

library(data.table) 
setDT(DF)[CJ(id = id, st.name = st.name, unique=TRUE), on=.(id, st.name)] 
+1

Красивые. Крошечная нота: 'unite' принимает аргумент' sep', поэтому 'unite (new_id, id, st.name, sep = '')' не даст разделителя, как в примере OP (обновлен). Или что-то вроде «сеп» мы приземляемся. –

+1

спасибо @ tad-dallas – KMR

+1

Я думаю, что аналог data.table для вашего слияния - это что-то вроде 'setDT (DF) [CJ (id = id, st.name = st.name, unique = TRUE), on =. (id, st.name)] ' – Frank

Смежные вопросы