

３つ目のfor文がなぜエラーになるのか、わかる方いらっしゃいますか？

下記のコードは各オブジェクト作成からfor文の処理まで一部始終のコードと、途中からの出力結果となります。

とてもシンプルに書いているつもりなのですが、同じ構成の３つ目のfor文でエラーがでます。

ご存知の方いらっしゃいましたらご教授のほどお願いいたします。

環境は Windows 10 です。

### 書いたコード

[code]

    av <- 1:8    #各ベクトル作成
    bv <- 1:20
    cv <- 1:40
    
    avm <- av %>% matrix(nrow = 4) %>% as.data.frame()　　#各データフレーム作成
    bvm <- bv %>% matrix(nrow = 4) %>% as.data.frame()
    cvm <- cv %>% matrix(nrow = 4) %>% as.data.frame()
    
    name1 <- letters[1:2]　　#準備
    name2 <- letters[1:5]
    name3 <- letters[1:10]
    
    colnames(avm) <- name1　　#各列名入れ
    colnames(bvm) <- name2
    colnames(cvm) <- name3
    
    avm;bvm;cvm　　#確認
    
    for (i in 1:2) {
      a <- avm %>% filter(avm[i]<avm[4,i]) %>% select(name1[i])
      a %>% print()
    } 
    
    for (i in 1:5) {
      a <- bvm %>% filter(bvm[i]<bvm[4,i]) %>% select(name2[i])
      a %>% print()
    } 
    
    for (i in 1:10) {
      a <- cvm %>% filter(cvm[i]<cvm[4,i]) %>% select(name3[i])
      a %>% print()
    } 
    
[/code]

### 出力結果 (途中から)

[code]

    > avm;bvm;cvm　　#確認
      a b
    1 1 5
    2 2 6
    3 3 7
    4 4 8
      a b  c  d  e
    1 1 5  9 13 17
    2 2 6 10 14 18
    3 3 7 11 15 19
    4 4 8 12 16 20
      a b  c  d  e  f  g  h  i  j
    1 1 5  9 13 17 21 25 29 33 37
    2 2 6 10 14 18 22 26 30 34 38
    3 3 7 11 15 19 23 27 31 35 39
    4 4 8 12 16 20 24 28 32 36 40
    
    > for (i in 1:2) {
       a <- avm %>% filter(avm[i]<avm[4,i]) %>% select(name1[i])
       a %>% print()
     } 
      a
    1 1
    2 2
    3 3
      b
    1 5
    2 6
    3 7
    
    > for (i in 1:5) {
       a <- bvm %>% filter(bvm[i]<bvm[4,i]) %>% select(name2[i])
       a %>% print()
     } 
      a
    1 1
    2 2
    3 3
      b
    1 5
    2 6
    3 7
       c
    1  9
    2 10
    3 11
       d
    1 13
    2 14
    3 15
       e
    1 17
    2 18
    3 19
    
    > for (i in 1:10) {
       a <- cvm %>% filter(cvm[i]<cvm[4,i]) %>% select(name3[i])
       a %>% print()
     } 
     エラー: Problem with `filter()` input `..1`.
    i Input `..1` is `cvm[i] < cvm[4, i]`.
    x undefined columns selected
    Run `rlang::last_error()` to see where the error occurred.
    
[/code]


CC BY-SA 4.0
2021-10-11T22:29:42.510
83017
2021-10-18T02:54:16.840
2021-10-18T02:53:23.857
3060
47641
question
r
同じ構成のfor文でも、処理数を増やすとエラーが出るようになる


皆様、どうもありがとうございました。

コメントにて解決策が提示されていましたので、他詳細をまとめて記載させていただきます。  
以下、まとめです。

**今回の問題点** ：  
ループ変数にしていた `i` が、指定データフレームの列名称 `i` と重複していた

**解決手段** ：  
for文のループ変数の変更（`i` から `idx` へ変更）

### 解決後の出力結果：

[code]

    > for (idx in 1:10) {
    +   a <- cvm %>% filter(cvm[idx]<cvm[4,idx]) %>% select(name3[idx])
    +   a %>% print()
    + } 
      a
    1 1
    2 2
    3 3
      b
    1 5
    2 6
    3 7
       c
    1  9
    2 10
    3 11
       d
    1 13
    2 14
    3 15
       e
    1 17
    2 18
    3 19
       f
    1 21
    2 22
    3 23
       g
    1 25
    2 26
    3 27
       h
    1 29
    2 30
    3 31
       i
    1 33
    2 34
    3 35
       j
    1 37
    2 38
    3 39
    
[/code]


CC BY-SA 4.0
2021-10-12T12:32:58.033
83047
2021-10-18T02:54:16.840
2021-10-18T02:54:16.840
3060
47641
83017
answer


質問への回答に対してやや蛇足なので本来はコメント欄に書くべきとは思いますが, コメント欄ではテキストの整形ができないため回答として書きます.

`%>%` などを使っていることから tidyverse を使用している前提で言いますと, tidyverse の機能を使うようにすれば `i`, `j`,
`idx` のようなインデックス専用の変数を使うことがなくなり, `i` や `idx`
といった列名がデータフレームにあったとしてもバッティングすることがなくなります.

まず, `select` には列インデックスも指定できるため, `name3(idx)` のような書き方はそもそも不要です.

[code]

    require(tidyverse)  # 質問文には書かれていないが元コードは明らかに tidyverse 読み込まないと動作しないため
    cvm <- data.frame(matrix(1:40, nrow = 4)) %>% setNames(letters[1:10])
    
    for(idx in 1:10) filter(cvm, cvm[idx] < cvm[4, idx]) %>% select(idx) %>% print()
    
[/code]

`filter` に関しても, `across` または `filter_at` を使って列インデックスを指定できます.

[code]

    for(idx in 1:10) filter(cvm, across(idx, ~. < .[4])) %>% select(idx) %>% print()
    
    # ただし filter_at は非推奨
    for(idx in 1:10) filter_at(cvm, idx, ~. < .[4]) %>% select(idx) %>% print()
    
[/code]

さらに, for文ではなく `map` や `walk` も使えばこうなります

[code]

    walk(1:10, ~filter(cvm, across(.x, ~. < .[4])) %>% select(.x) %>% print)
    
[/code]


CC BY-SA 4.0
2021-10-17T14:29:05.510
83147
2021-10-17T14:29:05.510
40575
83017
answer