6

私はRを初めて使用しています/データを簡単に再編成するオプションがあり、解決策を探しましたが、やりたいことを正確に見つけることができません. Reshape2 のメルト/キャストはうまく機能していないようで、ここに含めるほど十分に plyr を習得していません。

基本的に、以下に概説する構造を持つdata.frameがあり、各要素がカテゴリの可変長リストであるカテゴリ列があります(#列がはるかに大きいため、よりコンパクトであり、実際に複数のcategory_listsを持っています別々にしておくのが好きです):

>mydf
       ID      category_list    xval    yval
1     ID1   cat1, cat2, cat3   xnum1   ynum1
2     ID2         cat2, cat3   xnum2   ynum2
3     ID3               cat1   xnum3   ynum3

因子としてカテゴリ (および関連する値、つまり列 3/4) を操作したいので、ID と x/y/その他の列の値がカテゴリ リストの長さ:

       ID           category    xval    yval
1     ID1               cat1   xnum1   ynum1
2     ID1               cat2   xnum1   ynum1
3     ID1               cat3   xnum1   ynum1
4     ID2               cat2   xnum2   ynum2
5     ID2               cat3   xnum2   ynum2
6     ID3               cat3   xnum2   ynum2

category_list に factor/facet の別の解決策がある場合、それはより簡単な解決策になりますが、これをサポートするメソッドに遭遇していません。たとえば、次のようにエラーがスローされます。

>ggplot(mydf, aes(x=x, y=y)) + geom_point() + facet_grid(~cat_list)

layout_base(data, cols, drop = drop) のエラー: 少なくとも 1 つのレイヤーに、ファセットに使用されるすべての変数が含まれている必要があります

ありがとう!

4

6 に答える 6

9

答えはの形式によって異なりますcategory_list。実際にそれがlist各行の場合

何かのようなもの

mydf <- data.frame(ID = paste0('ID',1:3), 
 category_list = I(list(c('cat1','cat2','cat3'),  c('cat2','cat3'), c('cat1'))), 
 xval = 1:3, yval = 1:3)

また

library(data.table)
mydf <- as.data.frame(data.table(ID = paste0('ID',1:3), 
 category_list = list(c('cat1','cat2','cat3'),  c('cat2','cat3'), c('cat1')), 
 xval = 1:3, yval = 1:3) )

次に、を使用plyrmergeて長い形式のデータを作成できます

 newdf <- merge(mydf, ddply(mydf, .(ID), summarize, cat_list = unlist(category_list)), by = 'ID')


   ID    category_list xval yval cat_list
1 ID1 cat1, cat2, cat3    1    1     cat1
2 ID1 cat1, cat2, cat3    1    1     cat2
3 ID1 cat1, cat2, cat3    1    1     cat3
4 ID2       cat2, cat3    2    2     cat2
5 ID2       cat2, cat3    2    2     cat3
6 ID3             cat1    3    3     cat1

またはを必要としない非プライヤーアプローチmerge

 do.call(rbind,lapply(split(mydf, mydf$ID), transform, cat_list = unlist(category_list)))
于 2013-01-09T01:03:26.143 に答える
5

うんざりしているが一見堅牢なソリューション:

## Some example data
df <- as.data.frame(cbind(ID = paste0("ID", 1:2), 
                          category_list = list(4:1, 2:3), 
                          xvar = 8:9, 
                          yvar = 10:9))

## Calculate number of times each row of df will be repeated 
nn <- sapply(df$category_list, length)  
ii <- rep(seq_along(nn), times=nn)       

## Reshape data.frame
transform(df[ii,], 
          category = unlist(df$category_list),
          category_list = NULL, 
          row.names = NULL)
#    ID xvar yvar category
# 1 ID1    8   10        4
# 2 ID1    8   10        3
# 3 ID1    8   10        2
# 4 ID1    8   10        1
# 5 ID2    9    9        2
# 6 ID2    9    9        3
于 2013-01-09T00:56:50.490 に答える
2

可能性:

x <- read.table(textConnection('
    ID      category_list    xval    yval
     ID1   "cat1, cat2, cat3"   xnum1   ynum1
     ID2         "cat2, cat3"   xnum2   ynum2
     ID3               "cat1"   xnum3   ynum3'),
          header=TRUE,stringsAsFactors=FALSE)

library(plyr)
ddply(x,"ID",transform,category=strsplit(category_list,",")[[1]])

##    ID    category_list  xval  yval category
## 1 ID1 cat1, cat2, cat3 xnum1 ynum1     cat1
## 2 ID1 cat1, cat2, cat3 xnum1 ynum1     cat2
## 3 ID1 cat1, cat2, cat3 xnum1 ynum1     cat3
## 4 ID2       cat2, cat3 xnum2 ynum2     cat2
## 5 ID2       cat2, cat3 xnum2 ynum2     cat3
于 2013-01-09T00:52:38.910 に答える
0

を使用した別のベース R の可能性by:

do.call(rbind,
by(mydf,
   mydf$ID,
   function(x) {
     data.frame(
                ID=x$ID,
                category_list = unlist(strsplit(x$category_list,",")),
                xval=x$xval,
                yval=x$yval
               ) 
   }
  )
)

結果:

       ID category_list  xval  yval
ID1.1 ID1          cat1 xnum1 ynum1
ID1.2 ID1          cat2 xnum1 ynum1
ID1.3 ID1          cat3 xnum1 ynum1
ID2.1 ID2          cat2 xnum2 ynum2
ID2.2 ID2          cat3 xnum2 ynum2
ID3   ID3          cat1 xnum3 ynum3
于 2013-01-09T01:35:26.913 に答える
0

これは、plyr 以外のアプローチになります。

cbind( x[ rep(1:nrow(x), 
              times=sapply(x$category_list, 
                            function(xx) sapply( strsplit(xx, ","), length) ) ),
          -2],    # to get rid of the old category column
       new_cats = unlist( strsplit(x$category_list, ",") ) )
 # this used Bolker's example. If these are factor will need to add `as.character`

     ID  xval  yval new_cats
1   ID1 xnum1 ynum1     cat1
1.1 ID1 xnum1 ynum1     cat2
1.2 ID1 xnum1 ynum1     cat3
2   ID2 xnum2 ynum2     cat2
2.1 ID2 xnum2 ynum2     cat3
3   ID3 xnum3 ynum3     cat1
于 2013-01-09T01:10:26.973 に答える
0

注:私の回答は、OPが実際に持っていると思われるものとは異なるデータ構造に基づいていたため、元の回答は削除されました。


シナリオ 1: 列はlist

@mnel のサンプル データの使用:

mydf <- data.frame(ID = paste0('ID',1:3), 
 category_list = I(list(c('cat1','cat2','cat3'),  c('cat2','cat3'), c('cat1'))), 
 xval = 1:3, yval = 1:3)

listCol_l「splitstackshape」パッケージからの使用

library(splitstackshape)
listCol_l(mydf, "category_list")
#     ID xval yval category_list_ul
# 1: ID1    1    1             cat1
# 2: ID1    1    1             cat2
# 3: ID1    1    1             cat3
# 4: ID2    2    2             cat2
# 5: ID2    2    2             cat3
# 6: ID3    3    3             cat1

unnest「tidyr」パッケージからの使用

library(tidyr)
unnest(mydf, "category_list")
#    ID category_list xval yval
# 1 ID1          cat1    1    1
# 2 ID1          cat2    1    1
# 3 ID1          cat3    1    1
# 4 ID2          cat2    2    2
# 5 ID2          cat3    2    2
# 6 ID3          cat1    3    3

シナリオ 2: 列が連結文字列である

@BenBolker のサンプル データの使用:

x <- read.table(textConnection('
    ID      category_list    xval    yval
     ID1   "cat1, cat2, cat3"   xnum1   ynum1
     ID2         "cat2, cat3"   xnum2   ynum2
     ID3               "cat1"   xnum3   ynum3'),
                header=TRUE,stringsAsFactors=FALSE)

cSplit「splitstackshape」パッケージからの使用

library(splitstackshape)
cSplit(x, "category_list", ",", "long")
#     ID category_list  xval  yval
# 1: ID1          cat1 xnum1 ynum1
# 2: ID1          cat2 xnum1 ynum1
# 3: ID1          cat3 xnum1 ynum1
# 4: ID2          cat2 xnum2 ynum2
# 5: ID2          cat3 xnum2 ynum2
# 6: ID3          cat1 xnum3 ynum3
于 2013-01-09T05:00:54.277 に答える