rag*_*esz 10 r apply dataframe
我有一个数据帧:
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
Run Code Online (Sandbox Code Playgroud)
我想基于现有列创建一个新列.像这样的东西:
if (df[['a']] == df[['b']]) {
df[['c']] <- df[['a']] + df[['b']]
} else {
df[['c']] <- df[['b']] - df[['a']]
}
Run Code Online (Sandbox Code Playgroud)
问题是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)
Run Code Online (Sandbox Code Playgroud)
我希望在R中有类似的东西.所以结果看起来像这样:
a b c
1 1 1 2
2 2 20 18
3 3 3 6
4 4 4 8
5 5 50 45
Run Code Online (Sandbox Code Playgroud)
akr*_*run 22
一个选项是ifelse矢量化版本if/else.如果我们为每一行执行此操作if/else,那么OP的pandas post中显示的可以在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
Run Code Online (Sandbox Code Playgroud)
这可以用其他方式写成
df$c <- with(df, ifelse(a==b, a+b, b-a))
Run Code Online (Sandbox Code Playgroud)
在原始数据集中创建"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])
Run Code Online (Sandbox Code Playgroud)
这是一个稍微混乱的代数方法:
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
Run Code Online (Sandbox Code Playgroud)
这个想法是根据测试打开或关闭"减号"操作符a==b.
如果您想要一个apply方法,那么另一种方法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
Run Code Online (Sandbox Code Playgroud)
使用 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
Run Code Online (Sandbox Code Playgroud)