[英]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.