2015-10-29 2 views
0

Так как название объясняет, я хотел бы создать фрейм данных. Посмотрите на пухе, который будет использоваться в качестве матрицы для:Создание столбцов фрейма данных на основе строк из другого фрейма данных

structure(c("2", "3", "8", "8", "10", "10", "11", "11", "11", 
      "11", "Frank", "Mark", "Greg", "Mati", "Paul", 
      "Cyntha", "Marcus", "Pablo", "Maggy", "Trist" 
), .Dim = c(10L, 2L), .Dimnames = list(NULL, c("i", "vec_names" 
))) 

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

Конечно, это означает, что длина столбцов будет отличаться, поэтому отсутствующие «строки» могут быть заполнены NA.

Желаемый результат:

2  3 8 10  11 
Frank Mark Greg Paul Marcus 
      Mati Cyntha Pablo 
         Maggy 
         Trist 

ответ

2

В базовой R, первое преобразование вашу матрицу (mymat) к data.frame, вы можете попробовать следующее:

df <- as.data.frame(mymat, stringsAsFactors=FALSE) # convert your df to a data.frame 
sp_df <- split(df, df$i) # split it according to "i" 
nb_row <- sapply(sp_df, nrow) # compute the number of rows in each so you can complete with NAs 
mapply(function(x, y) c(x$vec_names, rep(NA, max(nb_row)-y)), 
     x=sp_df, 
     y=nb_row) [, order(as.numeric(names(sp_df)))] # complete with NA when needed and keep only the second column. Finally, reorder the columns. 

РЕДАКТИРОВАНИЕ

Благодаря @Frank, здесь является простым способом перехода, разбивая только вектор имен (после преобразования в data.frame):

sp_nm = split(df$vec_names, df$i) 
do.call(cbind, lapply(sp_nm, `length<-`, max(lengths(sp_nm))))[, order(as.numeric(names(sp_nm)))] 

Оба способа дают следующие выходные данные

# 2  3  8  10  11  
#[1,] "Frank" "Mark" "Greg" "Paul" "Marcus" 
#[2,] NA  NA  "Mati" "Cyntha" "Pablo" 
#[3,] NA  NA  NA  NA  "Maggy" 
#[4,] NA  NA  NA  NA  "Trist" 
3

Вы можете использовать reshape2-х dcast перекроить в широка:

DF = data.frame(m) 

library(reshape2) 
DF$s <- ave(DF$i, DF$i, FUN = seq_along) 
res <- dcast(DF, s ~ i, value.var = "vec_names") 

    s  10  11  2 3 8 
1 1 Paul Marcus Frank Mark Greg 
2 2 Cyntha Pablo <NA> <NA> Mati 
3 3 <NA> Maggy <NA> <NA> <NA> 
4 4 <NA> Trist <NA> <NA> <NA> 

К сожалению, у вас есть столбец вам не нужно, s, а остальные столбцы упорядоченно лексикографически. Если вы хотите исправить это:

res$s <- NULL 
res[order(as.integer(names(res)))] 

     2 3 8  10  11 
1 Frank Mark Greg Paul Marcus 
2 <NA> <NA> Mati Cyntha Pablo 
3 <NA> <NA> <NA> <NA> Maggy 
4 <NA> <NA> <NA> <NA> Trist 
0

Попробуйте функцию распространения пакета tidyr. Это приблизится к тому, что вы ожидаете.

spread(data.frame(
    structure(c("2", "3", "8", "8", "10", "10", "11", "11", "11", 
           "11", "Frank", "Mark", "Greg", "Mati", "Paul", 
           "Cyntha", "Marcus", "Pablo", "Maggy", "Trist"), 
          .Dim = c(10L, 2L), .Dimnames = list(NULL, c("i", "vec_names")))), 
    "i", "vec_names") 

       10  11  2 3 8 
     1 <NA> <NA> Frank <NA> <NA> 
     2 <NA> <NA> <NA> Mark <NA> 
     3 <NA> <NA> <NA> <NA> Greg 
     4 <NA> <NA> <NA> <NA> Mati 
     5 Paul <NA> <NA> <NA> <NA> 
     6 Cyntha <NA> <NA> <NA> <NA> 
     7 <NA> Marcus <NA> <NA> <NA> 
     8 <NA> Pablo <NA> <NA> <NA> 
     9 <NA> Maggy <NA> <NA> <NA> 
     10 <NA> Trist <NA> <NA> <NA> 
+1

Это не выглядит очень близко к желаемому выходу операционного усилителя в. – Frank

Смежные вопросы