7

各行の最大 2 つの値を識別し、それらの列番号と値を提供するコードを作成しようとしています。

df = data.frame( car = c (2,1,1,1,0), bus = c (0,2,0,1,0),
                 walk = c (0,3,2,0,0), bike = c(0,4,0,0,1))

maxおよびmax.col関数を使用して、最大値に対してこれを行うことができました。

df$max = max.col(df,ties.method="first")
df$val = apply(df[ ,1:4], 1, max)

私が知る限り、2 番目に高い値に相当する関数は存在しないため、これを行うと少しややこしくなります。このコードを使用すると、2 番目に高い値が得られますが、(重要なことに) 同点の状況ではそうではありません。また、それは危険に見えます。

sec.fun <- function (x) {
  max( x[x!=max(x)] )
}

df$val2 <- apply(df[ ,1:4], 1, sec.fun)

元のデータを削除せず、3 番目、4 番目に高い値を見つけるために使用できるソリューションが理想的ですが、どちらも必須要件ではありません。

4

1 に答える 1

24

これを試して:

# a function that returns the position of n-th largest
maxn <- function(n) function(x) order(x, decreasing = TRUE)[n]

これはクロージャーなので、次のように使用できます。

> # position of the largest
> apply(df, 1, maxn(1))
[1] 1 4 3 1 4
> # position of the 2nd largest
> apply(df, 1, maxn(2))
[1] 2 3 1 2 1
> 
> # value of the largest
> apply(df, 1, function(x)x[maxn(1)(x)])
[1] 2 4 2 1 1
> # value of the 2nd largest
> apply(df, 1, function(x)x[maxn(2)(x)])
[1] 0 3 1 1 0

更新しました

なぜここで閉鎖を使用するのですか?

理由の 1 つは、次のような関数を定義できることです。

max2 <- maxn(2)
max3 <- maxn(3)

次に、それを使用します

> apply(df, 1, max2)
[1] 2 3 1 2 1
> apply(df, 1, max3)
[1] 3 2 2 3 2

利点が明らかかどうかはわかりませんが、私はこの方法が好きです。これはより機能的な方法だからです。

于 2012-04-24T11:33:49.737 に答える