回答編集履歴

3

2024/07/14 18:26

投稿

melian
melian

スコア20574

test CHANGED
@@ -29,3 +29,95 @@
29
29
  # 9 9 4 4 1 NA NA 1 0 0 2 0
30
30
  # 10 10 3 3 NA NA NA 0 0 2 0 0
31
31
  ```
32
+
33
+ ### 追記
34
+
35
+ > ①cbindの第二引数、apply前の「t」です。
36
+ > tは各1〜5の作成された列が入る変数を表している?
37
+
38
+ t は transpose(転置)関数です。例えば以下では 2x3 行列を 3x2 行列に変換しています。
39
+
40
+ ```
41
+ > a <- matrix(1:6, 2, 3)
42
+ > a
43
+ [,1] [,2] [,3]
44
+ [1,] 1 3 5
45
+ [2,] 2 4 6
46
+
47
+ > t(a)
48
+ [,1] [,2]
49
+ [1,] 1 2
50
+ [2,] 3 4
51
+ [3,] 5 6
52
+ ```
53
+
54
+ なぜこの様なことをしているかと言うと、`apply(..., 1, ...)` で返るデータフレームが5行10列になっているので、転置して10行5列のデータフレームにしないと元のデータフレーム(`df`: 10行6列)と結合できないからです。
55
+
56
+ > ②「t(apply(df[,2:6],~」」の「df[,2~」でなぜ「,」が必要か?
57
+ > すでにdfでデータフレームを指定しているので、何の引数を省略しているのでしょうか。
58
+
59
+ `df[,2:6]` という表記は「`df`の(全ての行の)2列目から6列目」を指しています。`df[行範囲, 列範囲]` という表記で取り出す部分を指定することができますが、範囲を省略すると全ての行、もしくは全ての列として処理されます。例えば `df[1:5,]` は「`df`の1行目から5行目(までの全ての列)」を指します。また、行や列の指定にはラベルを指定することもできます。例えば `df[,c("2回目", "3回目", "4回目")]` は「`df`の"2回目"列, "3回目"列, "4回目"列」を取り出します。
60
+
61
+ > ③バックスラッシュで整数を文字列下していることは分かりました。
62
+ > 「~ \(x) sapply(1:5, \~」のsapplyの前にある「(x)」ですが、
63
+ > 変数列名をつくるための変数?これにより各行の変数を示している?
64
+
65
+ バックスラッシュですが、これは R 4.1.0 から追加された表記方法で、無名関数(anonymous function)を表しています。なので、`(x)` や `(a, b)` は関数パラメータになります。
66
+ ```
67
+ # R 4.1.0 以降(function(...) ~ 表記でも可)
68
+ df <- cbind(df, t(apply(df[,2:6], 1, \(x) sapply(1:5, \(a, b) sum(a==b, na.rm=T), x))))
69
+
70
+ # R 4.1.0 よりも前のバージョン
71
+ df <- cbind(df, t(apply(df[,2:6], 1, function(x) sapply(1:5, function(a, b) sum(a==b, na.rm=T), x))))
72
+ ```
73
+
74
+ > ④「~(a, b) sum(a==b,~」でなぜ、1~5がにaとbに代入されていくのか?
75
+ > このように前に変数を置く構文がはじめてです。もう少し探してみます。
76
+
77
+ > ⑤「~sum(a==b, na.rm=T), x)~」のxは何をしているのか?
78
+ > この構文のxに意味することがわかりません。
79
+
80
+ 具体的に、5行目のデータでの処理を見てみます。
81
+
82
+ ```
83
+ # 5行目(No == 5)の1回目から5回目の測定データ
84
+ c(4, 3, 4, 3, 1)
85
+
86
+ # \(x) の x に c(4, 3, 4, 3, 1) が渡されます
87
+ apply(..., 1, \(c(4, 3, 4, 3, 1)) sapply(1:5, \(a, b) sum(a==b, na.rm=T), x)
88
+
89
+ # 次に sapply の引数である x が c(4, 3, 4, 3, 1) になります
90
+ sapply(1:5, \(a, b) sum(a==b, na.rm=T), c(4, 3, 4, 3, 1))
91
+
92
+ # 無名関数のパラメータとして 1:5 と c(4, 3, 4, 3, 1) が渡されることになりますが、
93
+ # パラメータ a にはそれぞれ 1 から 5 まで渡されて、パラメータ b は全て c(4, 3, 4, 3, 1)
94
+ # になります
95
+
96
+ \(1, c(4, 3, 4, 3, 1)) sum(a==b, na.rm=T)
97
+ \(2, c(4, 3, 4, 3, 1)) sum(a==b, na.rm=T)
98
+ \(3, c(4, 3, 4, 3, 1)) sum(a==b, na.rm=T)
99
+ \(4, c(4, 3, 4, 3, 1)) sum(a==b, na.rm=T)
100
+ \(5, c(4, 3, 4, 3, 1)) sum(a==b, na.rm=T)
101
+
102
+ # 最終的に以下が実行されることになります
103
+ sum(1==c(4, 3, 4, 3, 1), na.rm=T) => 1
104
+ sum(2==c(4, 3, 4, 3, 1), na.rm=T) => 0
105
+ sum(3==c(4, 3, 4, 3, 1), na.rm=T) => 2
106
+ sum(4==c(4, 3, 4, 3, 1), na.rm=T) => 2
107
+ sum(5==c(4, 3, 4, 3, 1), na.rm=T) => 0
108
+
109
+ # ここで、数値とベクタを比較すると logical型のベクタが返ります
110
+ > 1==c(4, 3, 4, 3, 1)
111
+ [1] FALSE FALSE FALSE FALSE TRUE
112
+ > 3==c(4, 3, 4, 3, 1)
113
+ [1] FALSE TRUE FALSE TRUE FALSE
114
+
115
+ # そして sum() 関数では TRUE は整数の 1, FALSE は 0 として集計されます。
116
+ > sum(1==c(4, 3, 4, 3, 1))
117
+ [1] 1
118
+ > sum(3==c(4, 3, 4, 3, 1))
119
+ [1] 2
120
+ ```
121
+
122
+ 以上の処理が1行目から10行目までのそれぞれの行で実行されます。
123
+

2

2024/07/13 11:23

投稿

melian
melian

スコア20574

test CHANGED
@@ -14,11 +14,10 @@
14
14
  )
15
15
 
16
16
  #
17
- df <- cbind(df, t(apply(df[,2:6], 1,
18
- function(x) sapply(1:5, function(x, y) sum(x==y, na.rm=T), x))))
17
+ df <- cbind(df, t(apply(df[,2:6], 1, \(x) sapply(1:5, \(a, b) sum(a==b, na.rm=T), x))))
19
18
  df
20
19
 
21
- # No 1回目 2回目 3回目 4回目 5回目 1 2 3 4 5
20
+ # No 1回目 2回目 3回目 4回目 5回目 1 2 3 4 5
22
21
  # 1 1 1 NA NA NA NA 1 0 0 0 0
23
22
  # 2 2 1 2 NA NA NA 1 1 0 0 0
24
23
  # 3 3 3 NA NA NA NA 0 0 1 0 0

1

2024/07/13 11:10

投稿

melian
melian

スコア20574

test CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```r
6
6
  df <- data.frame(
7
- No = seq(1, 10),
7
+ No = 1:10,
8
8
  `1回目` = c(1, 1, 3, 1, 4, 1, 4, NA, 4, 3),
9
9
  `2回目` = c(NA, 2, NA, 3, 3, 1, 1, NA, 4, 3),
10
10
  `3回目` = c(NA, NA, NA, NA, 4, 1, 3, NA, 1, NA),
@@ -15,7 +15,7 @@
15
15
 
16
16
  #
17
17
  df <- cbind(df, t(apply(df[,2:6], 1,
18
- function(x) sapply(seq(1, 5), function(x, y) sum(x==y, na.rm=T), x))))
18
+ function(x) sapply(1:5, function(x, y) sum(x==y, na.rm=T), x))))
19
19
  df
20
20
 
21
21
  # No 1回目 2回目 3回目 4回目 5回目 1 2 3 4 5