想要在R中创建一个新数据框,该数据框采用一组行,并以nrow
* nrow
* ncol
格式组合每个变体。
library(dplyr)
dat <- read.table(text =
" Animal Color Size
Cat Orange 10
Dog Black 20", header=TRUE)
想要这个输出:
Animal Color Size
Cat NA NA
Cat Orange NA
Cat Orange 10
Dog NA NA
Dog Black NA
Dog Black 20
R中是否有可以执行此操作的功能 - 类似于expand.grid
?
expand.grid(dat$Animal, dat$Color, dat$Size) %>% arrange(Var1, Var2, Var3) #Note: this does not give the correct answer.
我可以使用以下方式创建第一行数据的第一行:
dat <- c("Cat", "Orange", 10)
counter <- 1
datInner <- list()
for(i in 1:length(dat)){ # loops through 3x
# i <- 3
datInner[[i]] <- dat[1:i]
counter <- counter + 1
}
library(plyr)
# Adapted from http://stackoverflow.com/questions/17308551/do-callrbind-list-for-uneven-number-of-column
plyr::rbind.fill(lapply(datInner, function(y){as.data.frame(t(y),
stringsAsFactors = FALSE)}))
# V1 V2 V3
# 1 Cat <NA> <NA>
# 2 Cat Orange <NA>
# 3 Cat Orange 10
注意:将调用此函数类型为顺序树扩展矩阵(STEM)。它需要一个带有树的表,其中节点深度不同,仅列出末端节点,并将其转换为包含树的所有顺序组合的表。
答案 0 :(得分:2)
dplyr解决方案 - 不是很一般。
library(dplyr)
rbind(
dat %>%
group_by(Animal) %>%
summarize(Color = NA, Size = NA) %>%
ungroup(),
dat %>%
group_by(Animal, Color) %>%
summarize(Size = NA) %>%
ungroup(),
dat) %>% arrange(Animal)
# Animal Color Size
#1 Cat <NA> NA
#2 Cat Orange NA
#3 Cat Orange 10
#4 Dog <NA> NA
#5 Dog Black NA
#6 Dog Black 20
答案 1 :(得分:1)
应该有比这更有效的答案,这只是一个尝试!
m <- t(sapply(1:ncol(dat), function(i) c(1:i, rep(NA, (ncol(dat)-i)))))
m
# [,1] [,2] [,3]
#[1,] 1 NA NA
#[2,] 1 2 NA
#[3,] 1 2 3
#2. now i apply each row to original data (dat) Basically performing subset
m1 <- apply(dat, 1, function(i) apply(m, 1, function(j) i[j]))
data.frame(matrix(m1, byrow = T, ncol = ncol(dat)))
# X1 X2 X3
#1 Cat <NA> <NA>
#2 Cat Orange <NA>
#3 Cat Orange 10
#4 Dog <NA> <NA>
#5 Dog Black <NA>
#6 Dog Black 20
注意:最后一列是factor
,因为它位于matrix
答案 2 :(得分:0)
事实证明,for循环可以用比我最初想象的更容易的列表来解决这个问题,并且它可以推广到具有不同节点深度的nrows。它与joel在两行示例中的出色答案速度相同。但是,目前可以将其并行化,以便在使用Matrix之外更快速地读取。注意:如果有不同的节点深度,Joel和我自己的答案都需要unique
- 例如,NA代替数据表中的20个值。
library(dplyr)
datInner <- list()
for(i in 1:ncol(dat)){ datInner[[i]] <- dat[1:i] }; # foreach %dopar% for parallel
datInner %>% bind_rows