2013-09-15 5 views
2

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

treatmet1<-data.frame(id=c(1,2,7)) 
treatment2<-data.frame(id=c(3,7,10)) 
control<-data.frame(id=c(4,5,8,9)) 

Я хочу, чтобы создать новый фрейм данных, который является объединением тех, 3 и есть столбец индикатора, который принимает значение 1 для каждого.

experiment<-data.frame(id=c(1:10),treatment1=0, treatment2=0, control=0) 

где experiment$treatment1[1]=1 и т.д. и т.п.

Что такое лучший способ сделать это в R?

Спасибо!

ответ

5

Обновлено согласно @ Flodel:

kk<-rbind(treatment1,treatment2,control) 
    var1<-c("treatment1","treatment2","control") 
    kk$df<-rep(var1,c(dim(treatment1)[1],dim(treatment2)[1],dim(control)[1])) 
kk 

    id   df 
1 1 treatment1 
2 2 treatment1 
3 7 treatment1 
4 3 treatment2 
5 7 treatment2 
6 10 treatment2 
7 4 control 
8 5 control 
9 8 control 
10 9 control 

Если вы хотите в виде 1 и 0, вы можете использовать table

ll<-table(kk) 
ll 


    df 
id control treatment1 treatment2 
    1  0   1   0 
    2  0   1   0 
    3  0   0   1 
    4  1   0   0 
    5  1   0   0 
    7  0   1   1 
    8  1   0   0 
    9  1   0   0 
    10  0   0   1 

Если вы хотите как data.frame, то вы можно использовать reshape:

kk2<-reshape(data.frame(ll),timevar = "df",idvar = "id",direction = "wide") 

names(kk2)[-1]<-sort(var1) 
> kk2 
kk2 
    id control treatment1 treatment2 
1 1  0   1   0 
2 2  0   1   0 
3 3  0   0   1 
4 4  1   0   0 
5 5  1   0   0 
6 7  0   1   1 
7 8  1   0   0 
8 9  1   0   0 
9 10  0   0   1 
+1

+1. Учитывая, что они являются взаимоисключающими, первая форма ('kk') кажется местом начала. – Frank

+0

Я не уверен, почему, но в этом решении есть небольшая опечатка. имена (kk2) [- 1] <- c ("treat1", "treat2", "cont") должны быть именами (kk2) [- 1] <- c ("cont", "treat1", "treat2") , Кроме этого, это более быстрое решение моей проблемы. – Ignacio

+0

Я уже обновил это решение. Вы можете это проверить. – Metrics

2

Принимая

treatment1<-data.frame(id=c(1,2,7)) 
treatment2<-data.frame(id=c(3,7,10)) 
control<-data.frame(id=c(4,5,8,9)) 

Вы можете использовать это:

x <- c("treatment1", "treatment2", "control") 
f <- function(s) within(get(s), assign(s, 1)) 
r <- Reduce(function(x,y) merge(x,y,all=TRUE), lapply(x, f)) 
r[is.na(r)] <- 0 

Результат:

> r 
    id treatment1 treatment2 control 
1 1   1   0  0 
2 2   1   0  0 
3 3   0   1  0 
4 4   0   0  1 
5 5   0   0  1 
6 7   1   1  0 
7 8   0   0  1 
8 9   0   0  1 
9 10   0   1  0 
+0

Это действительно больше похоже на проблему типа «rbind». –

+0

@DWin, как использовать 'rbind' здесь, не вызывая' table' next? –

+0

Я отправлю свое понимание проблемы. –

3
df.bind <- function(...) { 

    df.names <- all.names(substitute(list(...)))[-1L] 
    ids.list <- setNames(lapply(list(...), `[[`, "id"), df.names) 
    num.ids <- max(unlist(ids.list)) 
    tabs  <- lapply(ids.list, tabulate, num.ids) 

    data.frame(id = seq(num.ids), tabs) 
} 

df.bind(treatment1, treatment2, control) 

# id treatment1 treatment2 control 
# 1 1   1   0  0 
# 2 2   1   0  0 
# 3 3   0   1  0 
# 4 4   0   0  1 
# 5 5   0   0  1 
# 6 6   0   0  0 
# 7 7   1   1  0 
# 8 8   0   0  1 
# 9 9   0   0  1 
# 10 10   0   1  0 

(. Обратите внимание, как он включает строку для id == 6)

+0

Если я хочу сделать эту параллель, мне просто нужно изменить lapply для mclapply? У меня более 10 наблюдений. – Ignacio

+2

Если у вас есть намного больше, чем 10 data.frames, я бы рекомендовал вам эффективно изучить данные, прежде чем переходить на сложные вещи, такие как параллельная обработка. Здесь типизация 'df.bind (var1, var2, ..., var25)' будет громоздкой, как вы можете себе представить. (BTW говорит нам, что детали с самого начала, возможно, были полезны.) Вместо многих data.frames, загрязняющих вашу среду, у вас должен быть один список, содержащий все 25 переменных, таких как my 'ids.list'. Если бы вы могли рассказать нам, как вы пришли для создания этих data.frames, мы могли бы помочь вам показать, как создать 'ids.list' вместо этого. – flodel

0

Это иллюстрирует то, что я представлял себе, чтобы быть rbind стратегия:

alldf <- rbind(treatmet1,treatment2,control) 
alldf$grps <- model.matrix(~ factor(c(rep(1,nrow(treatmet1)), 
              rep(2,nrow(treatment2)), 
              rep(3,nrow(control))))-1) 
dimnames(alldf[[2]])[2]<- list(c("trt1","trt2","ctrl")) 
alldf 
#------------------- 
    id grps.trt1 grps.trt2 grps.ctrl 
1 1   1   0   0 
2 2   1   0   0 
3 7   1   0   0 
4 3   0   1   0 
5 7   0   1   0 
6 10   0   1   0 
7 4   0   0   1 
8 5   0   0   1 
9 8   0   0   1 
10 9   0   0   1 
+0

Похоже на барокко. :-) –

+0

Вкус может отличаться. Я думаю, что по сравнению с вашим решением, которое намного легче понять. Я просто складываю данные на tp друг друга, а затем создаю набор манекенов с модельной матрицей для спецификаций OP, ... плюс он не искажает упорядочение переменной ID. –

+0

ну, это определенно не то, что происходит после OP: он хочет, чтобы дублированные идентификаторы сливались. Он также хочет строку для 'id == 6', несмотря на то, что она не появляется ни в одном из входов. – flodel

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