2014-09-18 2 views
0

data = data.frame (col1 = c ('m1', 'm1', 'm1', 'm2', 'm2', 'm2' , 'm3', 'm3'), class = c ('a', 'b', 'c', 'a', 'b', 'c', 'a', 'b')) У меня есть data.frame с 2 столбцами, 1-й столбец - это список моделей, а второй столбец - список атрибутов модели. Мне нужно показать комбинацию моделей на основе атрибутов, которыми они разделяют. Я получил список с помощью комбинации «на» функции следующим образом:Как преобразовать вывод '['] в информационный кадр

data= data.frame(col1=c('m1','m1','m1','m2','m2','m3'), class=c('a','b','c','a','b','c')) 

data.ls=by(data$col1, data$class,function(x) t(combn(x, 2))) 

Выход именно то, что мне нужно, но мне это нужно в формате data.frame вместо списка и от имени " класс, который появляется в верхней части каждого списка должны быть перечислены в третьей колонке:

# data$class: a 
# [,1] [,2] 
# [1,] m1 m2 
# [2,] m1 m3 
# [3,] m2 m3 
# Levels: m1 m2 m3 

Итак, я попытался это:

as.data.frame(do.call("rbind",data.ls)) 

Но выход показывает только сочетание „col1“ (используя значения id вместо имя), а не атрибут 'class', который был наверху каждого списка в выводе 'by'. Выход do.call выглядит следующим образом:

# V1 V2 
# 1 1 2 
# 2 1 2 
# 3 1 3 

попытался Также это:

do.call("rbind.data.frame",data.ls) 

И получил эту ошибку: Ошибка в NextMethod(): недопустимое значение

Финальный стол должен выглядеть как это:

data.final= data.frame(col1=c('m1','m1','m1'), col2=c('m2', 'm2', 'm3'), class=c('a','b','c')) 

@Richard Scrivens предложил следующее:

newDF <- data.frame(do.call(rbind, lapply(data.ls, as.character)), names(data.ls), row.names = NULL) 

Выход:

X1 X2 X3 X4 X5 X6 names.data.ls. 
1 m1 m1 m2 m2 m3 m3    a 
2 m1 m1 m2 m2 m3 m3    b 
3 m1 m2 m1 m2 m1 m2    c 

Выход в этом формате, мне менее понятно, в перспективе комбинаций, чем «на» списке.

Любая помощь будет оценена по достоинству. Благодарю.

+0

as.data.frame не использования? – hd1

+0

Возможно, вы можете использовать 'aggregate', чтобы начать с' aggregate (col1 ~ class, data, function (x) t (combn (x, 2)))?? –

+0

@RichardScriven tapply example ---- tab <- do.call (rbind, with (data, { tapply (as.character (col1), class, function (x) c (combn (x, 2))) })) ---- работает отлично. Большое спасибо за вашу помощь! – LuluPor

ответ

0

Вы можете избежать этого, используя tapply, а не by. Фактически, tapply является функцией рабочей лошадки для by. Следующий результат просто необходим cbind и as.data.frame, но вы можете увидеть точку.

do.call(rbind, with(data, { 
    tapply(as.character(col1), class, function(x) c(combn(x, 2))) 
})) 
# [,1] [,2] 
# a "m1" "m2" 
# b "m1" "m2" 
# c "m1" "m3" 

Для того же результата, ваш by вызов может быть изменен немного.

> do.call(rbind, lapply(by(data$col1, data$class, combn, 2), as.character)) 
# [,1] [,2] 
# a "m1" "m2" 
# b "m1" "m2" 
# c "m1" "m3" 
+0

Спасибо @ Richard Scriven. В этом примере ваше решение работает в принципе.Но когда я получаю более 1 комбинации для одного класса, тогда я не уверен, как читать результат. Я сделаю небольшое изменение к оригинальному примеру, чтобы сделать это. – LuluPor

+0

@LuluPor - попробуйте мое редактирование с помощью решения 'tapply'. –

0

'совокупный' выход, кажется, что вы хотите:

aggregate(col1~class,data,function(x) t(combn(x, 2))) 
    class col1.1 col1.2 
1  a  m1  m2 
2  b  m1  m2 
3  c  m1  m3