2014-12-13 5 views
0

Мой набор данных выглядит следующим образом:Создание столбца в R, содержащих верхнюю п высшую строку

group <- c(1,2,3,4,5,6,7) 
    item1.sep <- sample(1:10,7) 
    item2.sep <- sample(1:10,7) 
    item3.sep<- sample(1:10,7) 
    item4.sep<- sample(1:10,7) 
    item5.sep<- sample(1:10,7) 
    item1.oct<- sample(1:10,7) 
    item2.oct <- sample(1:10,7) 
    item3.oct<- sample(1:10,7) 
    item4.oct<- sample(1:10,7) 
    item5.oct<- sample(1:10,7) 

df <- data.frame(group,item1.sep,item2.sep,item3.sep,item4.sep,item5.sep, 
       item1.oct,item2.oct,item3.oct,item4.oct,item5.oct) 


    group item1.sep item2.sep.... item5.oct 
     1  9   9    4 
     2  4   4    7 
     3  7   7    2 
     4  3   8    5 
     5  8   3    1 
     6  6   10    8 
     7  10   2    6 

И я хочу, чтобы создать 2 новых столбцов, содержащих верхний элемент 2 в качестве символа для каждого месяца. Может быть, сочетание максимального и слияния помогло бы в этом одном

  Top2_Sept Top2_Oct    group.... item5.oct 
item3.sep,item2.sep item5.Oct,item2.Oct  1   9 
item4.sep,item1.sep  .     2   4   
item2.sep,item5.sep  .     .   . 
item4.sep,item2.sep  .     .   . 
item1.sep,item3.sep  .     .   . 
item2.sep,item5.sep  .     .   . 
item4.sep,item1.sep  .     .   
+0

Извините, что, кажется, я могу принять только одно, кроме вас, также правильно. Спасибо. – jbest

+1

Нет проблем. Спасибо за ответ. – akrun

ответ

2

Вот data.table решение.

library(data.table) 
DT <- as.data.table(df) 
DT[,Top2_Sept:=paste(names(.SD)[order(unlist(.SD),decreasing=TRUE)[1:2]],collapse=","), 
      .SDcols=2:6,by=group] 
DT[,Top2_Oct:=paste(names(.SD)[order(unlist(.SD),decreasing=TRUE)[1:2]],collapse=","), 
      .SDcols=7:11,by=group] 
DT[,list(group,Top2_Sept,Top2_Oct)] 
# group   Top2_Sept   Top2_Oct 
# 1:  1 item5.sep,item3.sep item2.oct,item1.oct 
# 2:  2 item2.sep,item4.sep item1.oct,item5.oct 
# 3:  3 item5.sep,item3.sep item3.oct,item2.oct 
# 4:  4 item4.sep,item1.sep item5.oct,item1.oct 
# 5:  5 item2.sep,item4.sep item4.oct,item5.oct 
# 6:  6 item1.sep,item2.sep item1.oct,item2.oct 
# 7:  7 item1.sep,item2.sep item1.oct,item2.oct 

Ваш пример не вполне воспроизводимы, потому что вы сделали не set.seed(...) до создания случайных выборок. Результат, указанный выше, будет воспроизводиться, если вы начинаете set.seed(1).

Кроме того, в ваших правилах есть двусмысленность. Предположим, что item1.sep:item5.sep для данной строки - (8,7,7,6,5). Тогда верхний элемент находится в первом столбце, но второй элемент может находиться во втором или третьем столбце. Вы не представляете никаких правил для решения этого.

+1

Согласитесь на важность использования 'st.seed (...)' для создания воспроизводимых примеров! – PavoDive

1

Попробуйте

lst1 <- split(colnames(df)[-1],sub(".*\\.", '',colnames(df)[-1])) 
df[paste("Top2", c("Oct", "Sept"), sep="_")] <- lapply(lst1, function(x) { 
      nm1 <- colnames(df[x]) 
      apply(df[x], 1, function(.x) 
      toString(nm1[order(.x, decreasing=TRUE)[1:2]]))}) 

Или

lst1 <- lapply(month.abb[9:10], function(x) 
     df[grep(x, colnames(df), ignore.case=TRUE)]) 
nm1 <- lapply(lst1, colnames) 
f1 <- function(x,y) apply(x, 1, function(.x) 
      toString(y[order(.x, decreasing=TRUE)[1:2]])) 

df[paste('Top2', month.abb[9:10], sep="_")] <- Map(f1, lst1, nm1) 
Смежные вопросы