【问题标题】:r order of dataframe and selectionr 数据框的顺序和选择
【发布时间】:2013-11-04 22:29:40
【问题描述】:

如果有人可以指导我如何解决矩阵的复杂排序和选择每个子类别中的前 2 个元素,我将不胜感激。

代码:

index<-1:14
metric<-c(0.037777,0.041143,0.041043,0.042056,0.043701,0.042169,0.042134,
          0.046565,0.044638,0.036653,0.046221,0.04033,0.045385,0.043873)
cat_1<-c("California Munis","California Munis","California Munis","California Munis",
         "California Munis","California Munis","California Munis","Corporate Bonds",
         "Corporate Bonds","Corporate Bonds","Government Bonds","Government Bonds",
         "High Yield Bonds","High Yield Bonds")
cat_2<-c("California Munis","Corporate Bonds","Corporate Bonds","Government Bonds",
         "High Yield Bonds","High Yield Bonds","High Yield Bonds","High Yield Bonds",
         "High Yield Bonds","High Yield Bonds","California Munis","California Munis",
         "Corporate Bonds","Corporate Bonds")

data<-data.frame(cbind(index,metric,cat_1,cat_2))

产生下面的矩阵

Ind Metric     Cat_1                Cat_2
1   0.037777    California Munis    California Munis
2   0.041143    California Munis    Corporate Bonds
3   0.041043    California Munis    Corporate Bonds
4   0.042056    California Munis    Government Bonds
5   0.043701    California Munis    High Yield Bonds
6   0.042169    California Munis    High Yield Bonds
7   0.042134    California Munis    High Yield Bonds
8   0.046565    Corporate Bonds     High Yield Bonds
9   0.044638    Corporate Bonds     High Yield Bonds
10  0.036653    Corporate Bonds     High Yield Bonds
11  0.046221    Government Bonds    California Munis
12  0.04033     Government Bonds    California Munis
13  0.045385    High Yield Bonds    Corporate Bonds
14  0.043873    High Yield Bonds    Corporate Bonds

鉴于上面的矩阵,我想根据 Cat_1、Cat_2 和 Metric 进行排序。我试过这个:

data[order(data[,3],data[,4],data[,2]),]

但是,如果 Cat_1 和 Cat_2 的条目相同,则它们应该是无关紧要的。例如,“California Munis”&“Corporate Bonds”=“Corporate Bonds”&“California Munis”。我希望得到的结果应该类似于以下矩阵中的结果

Ind Metric      Cat_1               Cat_2               Selection
1   0.037777    California Munis    California Munis    1
2   0.041143    California Munis    Corporate Bonds     1
3   0.041043    California Munis    Corporate Bonds     2
11  0.046221    Government Bonds    California Munis    1
4   0.042056    California Munis    Government Bonds    2
12  0.04033     Government Bonds    California Munis    
5   0.043701    California Munis    High Yield Bonds    1
6   0.042169    California Munis    High Yield Bonds    2
7   0.042134    California Munis    High Yield Bonds    
8   0.046565    Corporate Bonds     High Yield Bonds    1
13  0.045385    High Yield Bonds    Corporate Bonds     2
9   0.044638    Corporate Bonds     High Yield Bonds    
14  0.043873    High Yield Bonds    Corporate Bonds 
10  0.036653    Corporate Bonds     High Yield Bonds    

最后一列显示了我需要提取的每个子类别的前 2 行的选择。

任何想法或代码都将受到高度赞赏。

谢谢

【问题讨论】:

  • 目前尚不清楚您期望的排序方式如何。例如,索引 11 是如何排到第 4 行的?
  • 因为 c("Government Bonds","California Munis")=c("California Munis","Government Bonds") 所以与 11、4 和 12 分组相同,并且具有最高指标与 4 和 12 相比。这有意义吗?
  • 我会首先以一种照顾换向的方式定义类别,例如将 cat_1 和 cat_2 与 sep=" " 一起粘贴,然后在 " " 上进行 strsplit,然后对该字符向量进行排序,然后将其粘贴回一个字符串中……这些是您的类别。现在很容易为每个类别挑选出产量最高的两项。

标签: r selection


【解决方案1】:

请放弃使用data.frame(cbind(...))。只会让你伤心。

 newdat <- data[ with( data, 
                order( pmax( as.numeric(cat_1), as.numeric(cat_2) ), 
                       pmin( as.numeric(cat_1), as.numeric(cat_2) ) ,
                     - metric) ) , ]
 newdat$selection <- ave(index, 
                         first=pmax( as.numeric(newdat$cat_1), 
                                     as.numeric(newdat$cat_2) ), 
                        second= pmin( as.numeric(newdat$cat_1), 
                                      as.numeric(newdat$cat_2) ) ,
                         FUN=seq)
#-----------------------------------------
> newdat
   index   metric            cat_1            cat_2 selection
1      1 0.037777 California Munis California Munis         1
2      2 0.041143 California Munis  Corporate Bonds         1
3      3 0.041043 California Munis  Corporate Bonds         2
11    11 0.046221 Government Bonds California Munis         1
4      4 0.042056 California Munis Government Bonds         2
12    12 0.040330 Government Bonds California Munis         3
5      5 0.043701 California Munis High Yield Bonds         1
6      6 0.042169 California Munis High Yield Bonds         2
7      7 0.042134 California Munis High Yield Bonds         3
8      8 0.046565  Corporate Bonds High Yield Bonds         1
13    13 0.045385 High Yield Bonds  Corporate Bonds         2
9      9 0.044638  Corporate Bonds High Yield Bonds         3
14    14 0.043873 High Yield Bonds  Corporate Bonds         4
10    10 0.036653  Corporate Bonds High Yield Bonds         5

这里成功的要求是两个cat变量中的levels是一样的。如果不是,则将它们与levels(.) &lt;- union(levels(cat1, levels(cat_2)) 相同

【讨论】:

  • 非常感谢@DWin。第一部分与我的数据配合得非常好,但是我无法使其与您构建选择的方式一起工作。我怀疑是索引,因为它在我的完整数据集中不是连续的。 index 在 ave 函数中做了什么?再次感谢您
  • 您确定两列的层级构造相同吗?我提供的用于解决该潜在问题的代码不完整。
【解决方案2】:

我扩展我的评论

# introduce combined category
cat3 <- sapply(paste(data$cat_1,data$cat_2,sep=" "),function(x){paste(sort(strsplit(x," ")[[1]]), collapse=" ")})
data$cat_3 <- cat3
# order as desired
data1 <- data[order( cat_3 , -metric), ]
# label and select top 2 in each cat
data1$rankByCat <- unlist(sapply(unique(data1$cat_3), function(mycat, mydf)  {return(1:sum(mydf$cat_3==mycat))}, mydf=data1))
data1[data1$rankByCat < 3, !names(data1)%in%c("cat_3")]

【讨论】:

    【解决方案3】:

    @andrei

    我得到了排序部分,代码如下:

    #concacenate the 2 strings
    cat_3<-paste(data[,3],data[,4],sep="  ")
    
    #break the string to 2 (creates a list)
    temp_split<-strsplit(cat_3,"  ")
    
    #sort by row
    sort_split<-sapply(temp_split,sort)
    
    #bind split
    out<-cbind(data,t(sort_split))
    

    这是最好的写法吗?

    我将如何从这里开始选择每个类别的前 2 个?

    感谢您的帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多