【问题标题】:Using ifelse with conditional statements based on vector indices to loop down rows使用 ifelse 和基于向量索引的条件语句来循环行
【发布时间】:2019-10-22 21:55:24
【问题描述】:

基本上我有一个数据框。从此,我采用了 2 个新索引来向我指示将用于更改此数据集的每一行的值。我还有一个代码来替换我想要替换的值(基本上直到新索引指示的列更改为 0)。我只是不知道如何把这一切放在一起。

这是我最初使用的数据框,ind1 和 ind2 用于创建一个新的索引,我将它们作为单独的向量。

COL1 <- c(1,1,1,NA,1,1)
COL2 <- c(1,NA,NA,1,1,1)
COL3 <- c(1,1,1,1,1,1)
ind1 <- c(1,2,1,2,1,2)
ind2 <- c(3,3,2,3,3,3)
Data <- data.frame (COL1, COL2, COL3, ind1, ind2)
Data
COL1 COL2 COL3 ind1 ind2
1    1    1    1    3    
1    NA   1    2    3
1    NA   1    1    2   
NA   1    1    2    3
1    1    1    1    3
1    1    1    2    3

新的向量索引看起来像这样,目前不在数据框中

actual <- c(5,3,4,1,1,2)
prediction <- c(1,1,2,5,5,1)

基本上我希望该函数评估每一行的实际 > 预测,如果这是 true,那么它会在 该行上运行下面的函数

replace(Data, cbind(rep(1:NROW(Data), Data$ind1), sequence(Data$ind1)), 0)

如果实际 > 预测为 false,那么它会在 该行上运行下面的函数

replace(Data, cbind(rep(1:NROW(Data), Data$ind2), sequence(Data$ind2)), 0)

对于这个数据框示例,我希望输出是一个新的数据框,其中

Data2
COL1 COL2 COl3 ind1 ind2
1    1    1    1    3
1    1    1    2    3
1    1    1    1    2
0    0    0    2    3
0    0    0    1    3
0    0    1    2    3

到目前为止我尝试过的是......

Data2<- c()
for (i in 1:NROW (Data)) {if (actual < prediction) {
  Data2[i]<- replace(Data, cbind(rep(1:NROW(Data), Data$ind1), sequence(Data$ind1)), 0)
 } else {
  Data2[i]<- replace(Data, cbind(rep(1:NROW(Data), Data$ind2), sequence(Data$ind2)), 0)
 }  
}

这为我提供了 Data2 的列表输出列表。但我正在寻找的是一个新的数据框。

【问题讨论】:

  • @thelatemail 已修复,对不起,我写的很匆忙,但实际的向量是我在这个数据帧上使用应用函数得到的,对于这个例子,我只是通过一些随机的在那里
  • 我仍然没有真正遵循这一点。对于实际 > 预测的每一行,您会更改整个数据集中的数据吗?
  • 对于实际 > 预测的每一行,然后在该行上执行第一个函数。当评估不是实际的 > 预测时,第二个函数在该行上执行。我希望这个过程遍历所有行。
  • 您能提供一个您尝试过的代码示例吗?
  • @JamieVarney - 对我来说,该函数在单行上运行没有意义。作为replacement 的一部分,您正在为单行中的多行和多列编制索引。

标签: r


【解决方案1】:

在我们多次来回之后,我相信这是为您提供所需输出的答案。

COL1 <- c(1,1,1,NA,1,1)
COL2 <- c(1,NA,NA,1,1,1)
COL3 <- c(1,1,1,1,1,1)
ind1 <- c(1,2,1,2,1,2)
ind2 <- c(3,3,2,3,3,3)
Data <- data.frame (COL1, COL2, COL3, ind1, ind2)
actual <- c(5,3,4,1,1,2)
prediction <- c(1,1,2,5,5,1)

logic <- ifelse(actual > prediction, TRUE, FALSE)

逻辑向量的输出为:

> logic
[1]  TRUE  TRUE  TRUE FALSE FALSE  TRUE

data2<-Data
for (i in 1:NROW(Data)) {
  if (logic[i]) {
    data2[i,1:Data$ind2[i]] <- 1
  } else {
    data2[i,1:Data$ind1[i]] <- 0
  }
}

循环输出如下。

> data2
  COL1 COL2 COL3 ind1 ind2
1    1    1    1    1    3
2    1    1    1    2    3
3    1    1    1    1    2
4    0    0    0    2    3
5    0    0    0    1    3
6    1    1    1    2    3

它与您的输出不同,因为逻辑输出在第六个位置为真。

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    我将通过以下方式解决问题。但是,我没有完全理解您的替换逻辑。出于这个原因,我把它省略了。

    下面将条件和替换逻辑分离成一个函数。因此,您只需使用apply 再次调用它即可轻松地将其用于其他数据帧。

    COL1 <- c(1,1,1,NA,1,1)
    COL2 <- c(1,NA,NA,1,1,1)
    COL3 <- c(1,1,1,1,1,1)
    ind1 <- c(1,2,1,2,1,2)
    ind2 <- c(3,3,2,3,3,3)
    
    actual <- c(5,3,4,1,1,2)
    prediction <- c(1,1,2,5,5,1)
    
    Data <- data.frame (
      col1 = COL1, col2 = COL2, col3 = COL3, ind1 = ind1, ind2 = ind2,
      actual = actual, prediction = prediction)
    
    custom.replace <- function(row) {
      # watch out! row is an atomic vector.
      if (row["actual"] > row["prediction"]) {
        # one of your replacement logic goes here.
      } else {
        # the other goes here.
      }
    }
    
    row.axis <- 1
    apply(Data, row.axis, custom.replace)
    

    我希望这会有所帮助!

    PS:我知道你想使用ìfelse 函数。但是,我不明白你为什么必须使用它。此外,您可以轻松扩展此解决方案,使其接收多个输入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-12-03
      • 2017-10-11
      • 1970-01-01
      • 2017-04-12
      • 1970-01-01
      • 2020-03-08
      • 2021-03-03
      相关资源
      最近更新 更多