【问题标题】:Skipping columns with certain values跳过具有特定值的列
【发布时间】:2018-03-02 21:12:37
【问题描述】:

我正在尝试编写for 循环来解决data.frame 上的以下等式:

a <- matrix(runif(n = 2151, 0, 0.5), nrow = 2151, ncol = 44) # matrix with certain values from 0.0 to 0.5
a <- data.frame(a) # save to data.frame
b <- runif(n = 2151, 0.9, 1) # generate values from 0.9 to 1 
a[ ,2] <- b # introducing higher values to data.frame

mean_error = numeric(0)
for(i in seq(1, length(a), 2)){ # iterate over 1st,3rd etc. column 
  if(a[[i]] < 0.9) { # skip the column if values are above value
    mean_err = mean(100 * abs(a[[i]] - a[[i + 1]] / mean(a[[i]] + a[[i + 1]]))) # calculate mean error of column
    mean_error = append(mean_error, mean_err) # save results
  }
}

它只是为我提供了前 2 列的平均误差,并进一步迭代给出 21 个值。我想让这个循环对列值的变化更敏感,并让它在遍历具有更高值(高于 1)的data.frame 时跳过第二列。显然,它不会省略第二列并产生错误的结果。我试图用if(a[[i]] &lt; 0.9) 解决这个问题,但它不起作用。还尝试melt()-ing 数据并遍历行,但没有太大成功。我将不胜感激任何解决这个问题的想法。谢谢!

【问题讨论】:

  • 只是为了确定,所以你想在跳过第二行的同时计算每列的平均误差?
  • 是的,完全正确。我想对第一列和第三列有平均错误。情况是,有时从我的实验室工作中获得的数据集不一定所有列的值都低于 0.9(这取决于 aparature 校准周期,然后引入具有更高值的列)。我想要一个区分大小写的循环。
  • 我怀疑它有一个更简单的解决方案。值 > 0.9 时,设置为 0 或从列中删除它们?您只想计算第 1 列和第 3 列或(1 和 3)的平均绝对误差,然后(3 和 5)等等?

标签: r loops dataframe iteration


【解决方案1】:

您在使用runif 时有一些错误,所以我创建了自己的a 版本,我认为它代表了您的意思。

我提供了两个选项,每个选项都以不同的形式给出结果,每个选项都以不同的方式处理您尝试跳过的第 2 列,希望您可以从两个选项之间得到您想要的。

创建虚拟数据:

a <- matrix(runif(n = 2000, min = 0, max = 0.5),nrow = 100, ncol = 20) 
a <-  data.frame(a) 
b <- runif(n = 100, min = 0.9, max = 1) 
a[, 2] <- b 

选项 1:使用 for-loop 遍历列,生成包含结果的 vector。这里第 2 列留为 0,这可能不太理想……

result <- vector(length = ncol(a))
for (i in 1:ncol(a)) {
  if(all(a[,i] < 0.9) == TRUE) {
  result[i]  <- mean(100 * abs(a[,i] - a[,i] + 1) / mean(a[,i] + a[,i] + 1))
    }
  }

result

选项 2:是使用 apply,这会导致 list 和本应跳过的第 2 列返回 NULL

apply(a, 2, function(x) {
  if(all(x < 0.9) == TRUE) {
    res <- mean(100 * abs(x - x + 1) / mean(x + x + 1))
  }
  }
)

然后,您可以轻松地从结果中删除所有 NULL 值。

【讨论】:

    【解决方案2】:

    @Manish Saraswat 您首先删除有问题的列的建议是正确的解决方案,@flee 提供的代码对我帮助很大。为了过滤不需要的列,我从 dplyr 包中使用了 select()。然后简单地使用sapply() 从创建的列表中删除 NULL 值。进一步的平均误差计算没有受到干扰。

    library(dplyr)
    a <- matrix(runif(n = 2151, 0, 0.5), nrow = 2151, ncol = 44) # matrix with values from 0.0 to 0.5
    a <- data.frame(a) # save to data.frame
    b <- runif(n = 2151, 0.9, 1) # generate values from 0.9 to 1 
    a[ ,2] <- b # introducing higher values to data.frame
    
    b=numeric(0) #vector to save results
    
    for (i in 1:length(a)) { # saves the right columns as list and sets rest as NULL
      if(all(a[i] < 0.8) == TRUE){
        b[i] = select(a,names(a[i]))   
      }
    }
    
    b[sapply(b, is.null)] <- NULL # removes NULLL from list
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多