2017-04-06 66 views
0

我有一个函数runBootstrap(取决于值#进行cat,其本身是test的产品),其输出result是可变长度的向量。道歉,这不是“最小”。如何将列添加到data.frame基于矢量长度

require(dplyr) 

test <- function(combo) { 
    if(combo[1] == 4) { 
    cat <- 4 
    } else if((combo[1] == 3 & combo[2] == 2) | (combo[1] == 2 & combo[2]  == 2)) { 
    cat <- 3 
    } else if((combo[1] == 2 & combo[2] == 1) | (combo[1] == 1 & combo[2]  == 2)) { 
    cat <- 2 
    } else { 
    cat <- 1 
    } 
} 

arg1.freqs <- c(0.5, 0.2, 0.1, 0.1) 
arg2.freqs <- c(0.8, 0.2) 

runBootstrap <- function(arg1.freqs, arg2.freqs) { 
    sim.df <- data.frame(x1 = 1:10000, y1 = NA) 
    sim.df$x1 <- sample(1:4, 10000, replace = TRUE, 
         prob = arg1.freqs)   
    sim.df$y1 <- sample(1:2, 10000, replace = TRUE, 
         prob = arg2.freqs) 
    sim.df$cat <- NA 
    for(i in 1:nrow(sim.df)) { 
    combo <- c(sim.df[i, 1], sim.df[i, 2]) 
    sim.df$cat[i] <- test(combo) 
    } 
    sim.df <- sim.df %>% 
    select(cat) %>% 
    group_by(cat) %>% 
    summarise(n = n()) %>% 
    mutate(freq = n/sum(n)) 
    sim.df <- as.data.frame(sim.df) 
    result <- c(sim.df[1, 3], sim.df[2, 3]) 
} 

在该当前版本只有两种值cat所以result是长度为2的向量;在未来的版本中,我将调整代码,以使length(result)等于#cat的值。

在for循环中使用该函数时,我想使用矢量值在已存在的data.frame中创建新列df1。迄今为止,我已经试过代码如下:

df1$result <- NA 
for (i in 1:nrow(df1)) { 
    df1$result[i] <- runBootstrap(arg1.freqs, arg2.freqs) 
} 

这显然不起作用,除非结果向量是长度= 1。但我不知道,直到函数运行的向量的长度(尽管一旦它运行,它将在每次迭代中具有相同的长度)。

我想什么来实现如下:

实施例1:如果长度(结果)== 2

df1.col x1 x2 
1  1 1 1 
2  2 2 2 
3  3 3 3 
4  4 4 4 
5  5 5 5 
6  6 6 6 

实施例2:如果长度(结果)== 3

df1.col x1 x2 x3 
1  1 1 1 1 
2  2 2 2 2 
3  3 3 3 3 
4  4 4 4 4 
5  5 5 5 5 
6  6 6 6 6 

感谢您的任何建议或方向。

  • 编辑澄清
  • 更新 - 与解决方案

我得到它的工作,因为我想通过创建一个空的列表,填充,然后使用rbind如下修改:

appendResults <- function(df1, arg1, arg2) { 
    my.list <- vector("list", nrow(df1)) 
    for (i in 1:nrow(df1)) {  
    arg1.freqs <- as.numeric(arg1[i, 3:6]) 
    arg2.freqs <- as.numeric(arg2[i, 3:4]) 
    my.list[[i]] <- runBootstrap(arg1.freqs, arg2.freqs) 
    } 
    result.df <- do.call(rbind, my.list) 
    df2 <- do.call(cbind, list(df1, result.df)) 
} 
+0

调用函数'function'会使读者和颜色突出显示系统混淆。提供一个函数示例,其功能与您的“函数”相同(在您尝试描述时会返回不同的长度)将帮助读者更快地理解您的问题并找到可行的解决方案。见http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – zeehio

+0

谢谢@zeehio,将更新澄清。 –

回答

0

检查这一个,不确定结果是什么样的,但是这会产生空列,等于结果的长度,带有NAs:

# fake data frame 
df1 <- data.frame(x = c(1,2,3), y = c("a", "b", "c")) 

# say result has length 3 
res <- c(5,6,7) 

# make columns with names x1, ..., x + length of res 
# and assign NA values to those column 
df1[ , paste("x", 1:length(res), sep = "")] <- NA 
+0

谢谢@din。我认为这会起作用。只需要玩弄位置(并学会编写更清晰的代码!)。 –

+0

@zeehio - 再次感谢。我用它做了一些修改,结果编辑如上。 –