【问题标题】:Repeating loop and adding columns in R重复循环并在 R 中添加列
【发布时间】:2019-12-31 12:27:06
【问题描述】:

我正在尝试构建一个 R 代码,它将占用我的循环并运行 20 次。每次我想在现有数据框中添加一列。在这里,我尝试了 3 次添加代码,但我觉得必须有一种更简单的方法来自动化它。我非常感谢任何帮助。

我的原始数据文件(称为“igel”)包含两列(“年份”和“网格”)和 1096 行。通过循环,我从“网格”列中选择一个随机数,并检查它之前是否被选择过。如果是,则将 0 添加到新列,如果不是,则添加 1。

代码如下:

a <- data.frame(matrix(ncol = 2, nrow = 0))
x <- c("number", "count")
colnames(a) <- x

for (i in 1:1096) {
num_i <- sample(igel$Grid, 1)
count_i <- c(if (num_i %in% a$number == TRUE) {0} else {1})
a<-a %>% add_row(number = num_i, count = count_i)
}

b <- data.frame(matrix(ncol = 2, nrow = 0))
x <- c("number", "count")
colnames(b) <- x

for (i in 1:1096) {
num_i <- sample(igel$Grid, 1)
count_i <- c(if (num_i %in% b$number == TRUE) {0} else {1})
b<-b %>% add_row(number = num_i, count = count_i)
}

c <- data.frame(matrix(ncol = 2, nrow = 0))
x <- c("number", "count")
colnames(c) <- x

for (i in 1:1096) {
num_i <- sample(igel$Grid, 1)
count_i <- c(if (num_i %in% c$number == TRUE) {0} else {1})
c<-c %>% add_row(number = num_i, count = count_i)
}

df.total<- cbind(a$count,b$count, c$count) 

【问题讨论】:

  • @Parfait,如何将行中的数字相加而不是将它们打印为 1 或 0?可以在代码中轻松实现吗?
  • 请在我的实际答案下方提问,而不是在您的问题下方提问。另外,你想总结一行的列作为结果吗?如果是这样,请查看colSums

标签: r loops repeat calculated-columns


【解决方案1】:

考虑 sapply 甚至它的包装器 replicate 并在向量计算中分别计算 numbercount,而不是逐行循环增长对象。

# RUNS 3 SAMPLES OF igel$Grid 1,096 TIMES (ADJUST 3 TO ANY POSITIVE INT LIKE 20)
grid_number <- data.frame(replicate(3, replicate(1096, sample(igel$Grid, 1))))

# RUNS ACROSS 3 COLUMNS TO CHECK CURRENT ROW VALUE IS INCLUDED FOR ALL VALUES BEFORE ROW
grid_count <- sapply(grid_number, function(col)
                       sapply(seq_along(col), function(i) 
                                 ifelse(col[i] %in% col[1:(i-1)], 0, 1)
                             )
                     )

虽然上面没有完全重现您的输出 df.total(矩阵而不是数据框),但由于迭代中的随机抽样,两者保持相似的结构:

dim(df.total)
# [1] 1096    3

dim(grid_count)
# [1] 1096    3

【讨论】:

  • 非常感谢您提供的代码!这完美地工作。但是,我觉得即使我在示例函数中添加“replace=FALSE”,它仍然会重新采样数据点。我希望得到具有相同数字的不同序列(有些出现多次,如果它们在起始样本中出现,这没关系)。 grid_number
  • 在每次迭代中,您只采样 1 个数字。如果您的样本量大于输入值的数量,则使用 replace=FALSE 将不同于 TRUE
  • 感谢您的意见。我设法通过使用以下代码来解决它:grid_number &lt;- data.frame(replicate(100, sample(igel_new$Grid,1096,replace=FALSE)))
【解决方案2】:

尽量避免遍历行。很少有必要,如果有的话。这是一种方法(将 n 替换为 1096,将 elem 替换为 igel$Grid):

n = 20
elem = 1:5
df.total = list()
for  (i in 1:5) {
    a = data.frame(number = sample(elem, n, replace=TRUE))
    a$count = as.numeric(duplicated(a$number))
    df.total[[i]] = a
}

df.total = as.data.frame(df.total)
df.total
##    number count number.1 count.1 number.2 count.2 number.3 count.3 number.4 count.4
## 1       4     0        2       0        5       0        4       0        1       0
## 2       3     0        5       0        3       0        4       1        3       0
## 3       5     0        3       0        4       0        2       0        4       0
## 4       5     1        1       0        2       0        5       0        3       1
## 5       2     0        4       0        2       1        5       1        5       0
## 6       4     1        2       1        2       1        5       1        5       1
## 7       5     1        1       1        3       1        2       1        4       1
## 8       5     1        2       1        5       1        5       1        4       1
## 9       2     1        1       1        1       0        1       0        1       1
## 10      3     1        1       1        5       1        4       1        1       1
## 11      5     1        3       1        1       1        3       0        5       1
## 12      2     1        1       1        2       1        5       1        1       1
## 13      3     1        5       1        4       1        5       1        4       1
## 14      1     0        4       1        2       1        4       1        1       1
## 15      4     1        4       1        2       1        5       1        1       1
## 16      4     1        2       1        5       1        2       1        5       1
## 17      3     1        1       1        1       1        3       1        2       0
## 18      2     1        2       1        2       1        2       1        2       1
## 19      2     1        3       1        1       1        2       1        1       1
## 20      1     1        3       1        2       1        1       1        3       1

【讨论】:

  • 非常感谢您提供的代码。我都试过了,效果都很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2013-04-24
  • 2023-03-04
  • 2023-03-28
相关资源
最近更新 更多