2012-03-06 3 views
2

Так что - я работаю с ФР, который получил эти группы повторных наблюдений проиндексированных идентификатором, например, так:Как изменить эти данные в R?

id | x1 | x2 | y1 | y2 
1 a b c 2 
1 a b d 3 
1 a b e 4 
2 ... 
2 ... 
... 

т.е. все переменные в каждой группе одинаковы, за исключением y1 и y2 (вообще говоря, y2 'изменяет' y1.) Все эти переменные, которые я здесь перечисляю, являются факторами. То, что я хотел бы сделать, чтобы превратить каждую из этих групп в нечто, похожее на следующем:

id | x1 | x2 | y1' | y2' | y3' 
1 a b c-2 d-3 e-4 
2 ... 

где у1 в (y1-прайм) является конкатенацией соседних значений y1 и y2, с тиром между. Однако число y1 отличается от id-group до id-group, но я был бы доволен очень широким фреймом данных, который позволяет использовать эти дополнительные функции в качестве решения. Во всяком случае, я (довольно бесполезно, должен признаться), попытался расплавить и отбросить эти данные с помощью reshape2, но на данный момент я не уверен, что я не буду делать это правильно, или этот пакет просто не является подходит для того, что я пытаюсь сделать здесь. Любой совет будет оценен - ​​спасибо!

ответ

1

Если я правильно понял вопрос правильно, вот способ сделать это с plyr:

foo <- read.table(textConnection("id x1 x2 y1 y2 
1 a b c 2 
1 a b d 3 
1 a b e 4"),header=TRUE) 


library("plyr") 

ddply(foo,.(x1,x2),with,{ 
     res <- data.frame(
      id = id[1], 
      x1 = x1[1], 
      x2 = x2[1]) 
     for (i in 1:length(y1)) 
     { 
      res[[paste("y",i,sep="")]] <- paste(y1,y2,sep="-")[i] 
     } 
     return(res) 
     } 
    ) 

Это возвращает:

id x1 x2 y1 y2 y3 
1 1 a b c-2 d-3 e-4 
1

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

foo <- read.table(textConnection("id x1 x2 y1 y2 
1 a b c 2 
1 a b d 3 
1 a b e 4 
2 a b f 2 
2 a b g 3 
2 a b h 4"),header=TRUE) 


new <- transform(foo, time.var=paste(id, x1, x2, sep=""), 
    y1=paste(y1, y2, sep="-"))[, -5] 

new <- data.frame(unique(foo[, 1:3]), t(unstack(new[, 4:5]))) 
names(new)[4:6] <- paste("y", 1:3, sep="") 
new 

Хотя я думаю, что ответ Sacha работает так же, как мой, если вы поставите идентификатор с использованием x1 и x2 (Я предполагаю, что это может быть более обобщенным):

ddply(foo,.(id, x1,x2),with,{ 
     res <- data.frame(
      id = id[1], 
      x1 = x1[1], 
      x2 = x2[1]) 
     for (i in 1:length(y1)) 
     { 
      res[[paste("y",i,sep="")]] <- paste(y1,y2,sep="-")[i] 
     } 
     return(res) 
     } 
    ) 

EDIT: Это решение может быть более обобщенным:

new <- transform(foo, y=paste(y1, y2, sep="-"), stringsAsFactors=FALSE) 
aggregate(y~id+x1+x2, new, c) 
0

Да, это то, что перекроить пакет F или. Сначала подготовьте ваши данные:

foo <- transform(foo, 
       y = paste(y1,y2, sep = "-"), 
       ix = unlist(tapply(id, id, function(gr) 1:length(gr)))) 

Затем продолжить преобразование:

mfoo <- melt(foo, measure.vars = "y") 
cast(mfoo, id + x1 + x2 ~ variable + ix) 

должны дать

id x1 x2 y_1 y_2 y_3 
1 1 a b c-2 d-3 e-4 
2 2 a b f-2 h-4 <NA> 

с набором данных

foo <- read.table(textConnection("id x1 x2 y1 y2 
1 a b c 2 
1 a b d 3 
1 a b e 4 
2 a b f 2 
2 a b g 3"),header=TRUE) 

[править: это изменить , с reshape2 вы должны использование dcast вместо cast]

+0

Кто бы ни отказался, должен быть расплавлен и переработан :) – VitoshKa

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