私はデータフレームを持っています:
_df <- data.frame('a'=c(1,2,3,4,5), 'b'=c(1,20,3,4,50))
df
a b
1 1 1
2 2 20
3 3 3
4 4 4
5 5 50
_
既存の列に基づいて新しい列を作成したい。このようなもの:
_if (df[['a']] == df[['b']]) {
df[['c']] <- df[['a']] + df[['b']]
} else {
df[['c']] <- df[['b']] - df[['a']]
}
_
問題は、最初の行についてのみif
条件がチェックされることです...上記のif
ステートメントから関数を作成する場合、apply()
(またはmapply()
...)、同じです。
Python/pandasでは、これを使用できます。
_df['c'] = df[['a', 'b']].apply(lambda x: x['a'] + x['b'] if (x['a'] == x['b']) \
else x['b'] - x['a'], axis=1)
_
Rでも似たようなものが欲しいので、結果は次のようになります。
_ a b c
1 1 1 2
2 2 20 18
3 3 3 6
4 4 4 8
5 5 50 45
_
1つのオプションはifelse
です。これは_if/else
_のベクトル化バージョンです。行ごとにこれを行う場合、OPのpandas投稿に示されている_if/else
_は、for
ループまたは_lapply/sapply
_のいずれかで実行できます。しかし、それはR
では非効率です。
_df <- transform(df, c= ifelse(a==b, a+b, b-a))
df
# a b c
#1 1 1 2
#2 2 20 18
#3 3 3 6
#4 4 4 8
#5 5 50 45
_
そうでなければ、これは
_df$c <- with(df, ifelse(a==b, a+b, b-a))
_
元のデータセットに「c」列を作成するには
OPはR
で同様のオプションを使用するため、_if/else
_を使用します
_df$c <- apply(df, 1, FUN = function(x) if(x[1]==x[2]) x[1]+x[2] else x[2]-x[1])
_
少し複雑な代数的方法を次に示します。
df$c <- with(df, b + ((-1)^((a==b)+1) * a))
df
a b c
1 1 1 2
2 2 20 18
3 3 3 6
4 4 4 8
5 5 50 45
考え方は、テスト「a==b
」に基づいて「マイナス」演算子をオンまたはオフにすることです。
適用メソッドが必要な場合、mapply
を使用する別の方法は、関数を作成して適用することです。
fun1 <- function(x, y) if (x == y) {x + y} else {y-x}
df$c <- mapply(fun1, df$a, df$b)
df
# a b c
#1 1 1 2
#2 2 20 18
#3 3 3 6
#4 4 4 8
#5 5 50 45
apply
を使用したソリューション
myFunction <- function(x){
a <- x[1]
b <- x[2]
#further values ignored (if there are more than 2 columns)
value <- if(a==b) a + b else b - a
#or more complicated stuff
return(value)
}
df$c <- apply(df, 1, myFunction)
Dplyrパッケージの使用:
library(dplyr)
df <- df %>%
mutate(c = if_else(a == b, a + b, b - a))
df
# a b c
# 1 1 1 2
# 2 2 20 18
# 3 3 3 6
# 4 4 4 8
# 5 5 50 45