簡體   English   中英

根據來自另一個數據框的行創建數據框的列

[英]Create columns of data frame based on rows from another 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的值創建列。 如果第i列中的數字相同,則意味着在下一列中可以找到的兩個名稱應存儲在新數據幀的一列中。

當然,這意味着列的長度會有所不同,因此缺失的“字符串”可以用NA填充。

所需的輸出:

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

您可以使用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

在基礎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"

嘗試使用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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM