【问题标题】:How to add columns to data.frame based on vector length如何根据向量长度将列添加到 data.frame
【发布时间】:2017-09-01 05:47:45
【问题描述】:

我有一个函数runBootstrap,其输出result 是一个可变长度的向量(取决于cat 的值的数量,它本身是test 的乘积)。很抱歉这不是“最小的”。

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))
}

【问题讨论】:

  • 调用函数function 会使读者和颜色突出显示系统感到困惑。提供一个行为类似于您的 function 的函数示例(在您尝试描述时返回不同的长度)将帮助读者更快地理解您的问题并找到有效的解决方案。见stackoverflow.com/questions/5963269/…
  • 感谢@zeehio,将更新澄清。

标签: r for-loop vector dataframe


【解决方案1】:

检查这个,不确定结果是什么样的,但这会创建空列,等于结果的长度,带有 NA:

# 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

【讨论】:

  • 谢谢@din。我认为这会奏效。只需要玩弄位置(并学习编写更简洁的代码!)。
  • @zeehio - 再次感谢。我得到了一些修补,上面编辑的结果。
猜你喜欢
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2021-04-19
  • 2015-05-16
  • 1970-01-01
相关资源
最近更新 更多