Dataframe 根据其他列创建新列
Dataframe create new column based on other columns
我有一个数据框:
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
一个选项是 ifelse
,它是 if/else
的矢量化版本。如果我们对每一行都这样做,OP 的 pandas post 中显示的 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
.
开启或关闭"minus"运算符
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)
如果你想要一个应用方法,那么 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
使用 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
我有一个数据框:
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
一个选项是 ifelse
,它是 if/else
的矢量化版本。如果我们对每一行都这样做,OP 的 pandas post 中显示的 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
.
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)
如果你想要一个应用方法,那么 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
使用 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