R: Вопрос о реорганизации таблицы - PullRequest
1 голос
/ 20 июля 2011

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

id,property1,property2,property3
1,1,0,0  
2,1,1,0  
3,0,0,1  
4,1,1,1

d.f <- structure(list(id = 1:4, property1 = c(1L, 1L, 0L, 1L), property2 = c(0L, 
1L, 0L, 1L), property3 = c(0L, 0L, 1L, 1L)), .Names = c("id", 
"property1", "property2", "property3"), class = "data.frame", row.names = c(NA, 
-4L))

Какой наименее громоздкий способ получить следующий фрейм данных:

id,properties_list
1,property1
2,property1, property2
3,property3
4,property1, property2, property3

Может быть, что-то вроде melt или reshape с необычными вариантами?

Ответы [ 3 ]

2 голосов
/ 20 июля 2011

Это на самом деле не правильный фрейм данных, который по необходимости имеет все строки с одинаковым количеством записей, поэтому правильный ответ - вам может понадобиться список.Если это не совсем то, что вам нужно, попробуйте следующее:

dfrm[-1] <- t( apply(dfrm[-1], 1, function(x) ifelse(x, names(x), "") )   )
dfrm
  id property1 property2 property3
1  1 property1                    
2  2 property1 property2          
3  3                     property3
4  4 property1 property2 property3

Вам нужен t (), потому что применяемые операции со строками транспонируют свои результаты из-за основного порядка столбцов, который навязывает R.

Если вы хотите использовать версию списка, вот один из подходов:

 prop_list <- apply(dfrm[-1], 1, function(x)  c(names(x)[ as.logical(x)]  ) )
 names(prop_list) <- dfrm[,1]
 prop_list
$`1`
[1] "property1"

$`2`
[1] "property1" "property2"

$`3`
[1] "property3"

$`4`
[1] "property1" "property2" "property3"
2 голосов
/ 20 июля 2011

Это решение предполагает, что вы ищете фрейм данных, аналогичный тому, как gsk3 интерпретировал вопрос (вставка свойств вместе), но с обязательным избеганием цикла for, просто потому, что мы катимся с R:

property_list <- apply(d.f[,-1],1,
                    FUN=function(x,nms){paste(nms[as.logical(x)],collapse=",")},
                        nms=colnames(d.f)[-1])

as.data.frame(cbind(d.f$id,property_list))


  V1                 property_list
1  1                     property1
2  2           property1,property2
3  3                     property3
4  4 property1,property2,property3
2 голосов
/ 20 июля 2011

На самом деле это совсем не новая форма. Используйте paste.

for(i in seq(1,3) ) {
   tf <- as.logical(d.f[,i+1])
   d.f[,i+1] <- as.character(d.f[,i+1])
   d.f[,i+1][tf] <- colnames(d.f)[i+1]
   d.f[,i+1][!tf] <- " "
}
d.f$property.list <- paste(d.f[,2],d.f[,3],d.f[,4],sep=" ")

Как всегда, вы получите лучшие ответы, если сначала dput() ваш фрейм данных:

d.f <- structure(list(id = 1:4, property1 = c(1L, 1L, 0L, 1L), property2 = c(0L, 
1L, 0L, 1L), property3 = c(0L, 0L, 1L, 1L)), .Names = c("id", 
"property1", "property2", "property3"), class = "data.frame", row.names = c(NA, 
-4L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...