STEM:创建R

时间:2017-01-20 02:47:06

标签: r matrix dplyr apply

想要在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)。它需要一个带有树的表,其中节点深度不同,仅列出末端节点,并将其转换为包含树的所有顺序组合的表。

3 个答案:

答案 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