【问题标题】:Condition and row and column with a double loop双循环条件和行列
【发布时间】:2017-12-09 11:27:42
【问题描述】:

我遇到了一个关于“下标越界”的问题,我想要的是获得每个观察值的第一个月和最后一个月,其中我有三个连续的“1”或“True”。我想在第一个月和最后一个月分别创建 2 个新列“开始”和“结束”。 在我的第一个观察示例中:开始等于 avril,结束等于 juin 在 5 观察:开始等于 fevrier,结束等于 avril 在 9 观察:开始等于 janvier,结束等于 mars ...

我试过这样做:

nom <- letters[1:5]
pseudo <- paste(name, 21:25, sep = "")
janvier <- c(0, 1, 1, 1, 0)
fevrier <- c(1, 1, 1, 1, 1)
mars <- c(0, 0, 0, 1, 1)
avril <- c(1, 1, 1, 0, 1)
mai <- c(1, 0, 1, 1, 1)
juin <- c(1, 1, 0, 1, 0)

df <- data.frame(nom =nom, pseudo = pseudo, janvier = janvier,
                 fevrier = fevrier, mars = mars, avril = avril,
                 mai = mai, juin = juin)

dfm <- as.matrix(df[, -c(1, 2)])

my_matrix <- matrix(nrow = 10, ncol = 6)


for(i in 1:dim(dfm)[1]){
  for(j in 1:dim(dfm)[2]){
    if(dfm[i, j] + dfm[i, j+1] + dfm[i, j+2] == 3){
      my_matrix[i, j] <- "periode_ok"
      my_matrix[i, j+1] <- "periode_ok"
      my_matrix[i, j+2] <- "periode_ok"
    } 
  }
}

输出应该是这样的:

begin <- c("avril", "no  info", "no info",
           "janvier", "fevrier", "avril", "no info",
           "no info", "janvier", "fevrier")
end <- c("juin", "no info", "no info", "mars",
         "avril", "juin", "no info", "no info",
         "mars", "avril")

output <- data.frame(nom =nom, pseudo = pseudo, janvier = janvier,
                 fevrier = fevrier, mars = mars, avril = avril,
                 mai = mai, juin = juin, begin = begin,end = end)

任何帮助将不胜感激

【问题讨论】:

  • for(j in 1:(dim(dfm)[2]-2)) 使用这个。
  • pseudo 的长度应为 5,与所有其他变量一样。
  • @DavidArenburg 我已经在另一篇文章中解决了您的问题。同时,我认为评论的语言和内容不符合 Be Nice 政策。干杯。

标签: r for-loop dataframe


【解决方案1】:

首先,像1:dim(dfm)[1]这样的构造是危险的,因为如果dim(dfm)[1]为零,您将获得完全有效的向量1:0,并且循环将尝试处理向量的零元素,在这种情况下,矩阵.这是非法的,会抛出错误。推荐的解决方案是使用seq_len(...)。 其次,我使用了nrowncol 而不是dim(dfm)[.]。 现在对于您遇到的错误。您正在尝试处理j + 1j + 2 列,因此当j 到达ncol(dfm) 时,您就没有债券了。下面的代码删除了循环限制的最后两个元素。

n <- ncol(dfm)
for(i in seq_len(nrow(dfm))){
  for(j in seq_len(n)[-c(n - 1, n)]){
    if(dfm[i, j] + dfm[i, j+1] + dfm[i, j+2] == 3){
      my_matrix[i, j] <- "periode_ok"
      my_matrix[i, j+1] <- "periode_ok"
      my_matrix[i, j+2] <- "periode_ok"
    } 
  }
}

my_matrix

【讨论】:

    【解决方案2】:

    当然有一个矢量化的解决方案,但是如果你想更正你的 for 循环,你需要将 j 限制为 dfm 的维度 - 2,因为你正在检查前面的两列。根据您提供的内容,这将对您有所帮助;但是,尚不清楚如何从df 的 5 行中获得 10 行(重复两次)。

          my_matrix <- matrix("no info", nrow = 5, ncol = 2)
          colnames(my_matrix) <- c("begin", "end")
    
    
          for(i in 1:dim(dfm)[1]){
            for(j in 1:(dim(dfm)[2]-2)){
              if(dfm[i, j] + dfm[i, j+1] + dfm[i, j+2] == 3){
                my_matrix[i, 1] <- colnames(dfm)[j]
                my_matrix[i, 2] <- colnames(dfm)[j+2]
                break
              } 
            }
          }
    
    
    output <- cbind(df, my_matrix)
    

    那么结果是:

    output
    
    #   nom pseudo janvier fevrier mars avril mai juin   begin     end 
    # 1   a name21       0       1    0     1   1    1   avril    juin 
    # 2   b name22       1       1    0     1   0    1 no info no info 
    # 3   c name23       1       1    0     1   1    0 no info no info 
    # 4   d name24       1       1    1     0   1    1 janvier    mars 
    # 5   e name25       0       1    1     1   1    0 fevrier   avril
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-22
      • 2020-11-25
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 2016-02-03
      相关资源
      最近更新 更多