2017-04-06 64 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 - 再次感謝。我用它做了一些修改,結果編輯如上。 –