如何使用数据框的输入创建函数并将其应用于所有行?
how to create function with input from dataframe and apply it over all rows?
我尝试在 R 中编写一个函数,它将数据框中的几个变量作为输入,并给出一个带有结果的向量作为输出。
基于下面这个post我确实写了下面的函数。
尽管我收到此警告消息:
the condition has length > 1 and only the first element will be used
我尝试通过下面的post在函数中使用sapply来解决它,但我没有成功。
https://datascience.stackexchange.com/questions/33351/what-is-the-problem-with-the-condition-has-length-1-and-only-the-first-elemen
# a data frame with columns a, x, y and z:
myData <- data.frame(a=1:5,
x=(2:6),
y=(11:15),
z=3:7)
myFun3 <- function(df, col1 = "x", col2 = "y", col3 = "z"){
result <- 0
if(df[,col1] == 2){result <- result + 10
}
if(df[,col2] == 11){result <- result + 100
}
return(result)
}
myFun3(myData)
> Warning messages:
> 1: In if (df[, col1] == 2) { :
> the condition has length > 1 and only the first element will be used
> 2: In if (df[, col2] == 11) { :
> the condition has length > 1 and only the first element will be used
谁能解释一下如何将函数应用于数据框的所有行?
非常感谢!
我们需要 ifelse
而不是 if/else
因为 if/else
没有矢量化
myFun3 <- function(df, col1 = "x", col2 = "y", col3 = "z"){
result <- numeric(nrow(df))
ifelse(df[[col1]] == 2, result + 10,
ifelse(df[[col2]] == 11, result + 100, result))
}
myFun3(myData)
#[1] 10 0 0 0 0
或者 OP 的代码可以在进行一些更改后 Vectorize
d,即用 else if
梯子
删除第二个 if
myFun3 <- Vectorize(function(x, y){
result <- 0
if(x == 2) {
result <- result + 10
} else if(y == 11){
result <- result + 100
} else result <- 0
return(result)
})
myFun3(myData$x, myData$y)
#[1] 10 0 0 0 0
关于 OP 对多个条件何时为 TRUE 的疑问,则只想执行第一个,ifelse
(嵌套 - 如果超过两个)或 if/else if/else
(else if
ladder 或 if/else 嵌套)都有效,因为它以我们指定条件的相同顺序执行,并且一旦出现 TRUE 条件它就会停止,即假设我们有多个条件
if(expr1) {
1
} else if(expr2) {
2
} else if(expr3) {
3
} else if(expr4) {
4
} else {
5}
首先检查第一个表达式 ('expr1'),然后检查第二个,依此类推。当它 return 为真时,它退出,即它是一个嵌套条件
if(expr1) {
1
} else {
if(expr2) {
2
} else {
if(expr3) {
3
} else {
if(expr4) {
4
} else 5
}
}
}
这样做是有代价的,即只要我们有更多的值匹配 1,就只执行 expr1 从而节省时间,但是如果有更多的 5 个值,那么所有这些条件都会被检查
我尝试在 R 中编写一个函数,它将数据框中的几个变量作为输入,并给出一个带有结果的向量作为输出。
基于下面这个post我确实写了下面的函数。
尽管我收到此警告消息:
the condition has length > 1 and only the first element will be used
我尝试通过下面的post在函数中使用sapply来解决它,但我没有成功。 https://datascience.stackexchange.com/questions/33351/what-is-the-problem-with-the-condition-has-length-1-and-only-the-first-elemen
# a data frame with columns a, x, y and z:
myData <- data.frame(a=1:5,
x=(2:6),
y=(11:15),
z=3:7)
myFun3 <- function(df, col1 = "x", col2 = "y", col3 = "z"){
result <- 0
if(df[,col1] == 2){result <- result + 10
}
if(df[,col2] == 11){result <- result + 100
}
return(result)
}
myFun3(myData)
> Warning messages:
> 1: In if (df[, col1] == 2) { :
> the condition has length > 1 and only the first element will be used
> 2: In if (df[, col2] == 11) { :
> the condition has length > 1 and only the first element will be used
谁能解释一下如何将函数应用于数据框的所有行? 非常感谢!
我们需要 ifelse
而不是 if/else
因为 if/else
没有矢量化
myFun3 <- function(df, col1 = "x", col2 = "y", col3 = "z"){
result <- numeric(nrow(df))
ifelse(df[[col1]] == 2, result + 10,
ifelse(df[[col2]] == 11, result + 100, result))
}
myFun3(myData)
#[1] 10 0 0 0 0
或者 OP 的代码可以在进行一些更改后 Vectorize
d,即用 else if
梯子
if
myFun3 <- Vectorize(function(x, y){
result <- 0
if(x == 2) {
result <- result + 10
} else if(y == 11){
result <- result + 100
} else result <- 0
return(result)
})
myFun3(myData$x, myData$y)
#[1] 10 0 0 0 0
关于 OP 对多个条件何时为 TRUE 的疑问,则只想执行第一个,ifelse
(嵌套 - 如果超过两个)或 if/else if/else
(else if
ladder 或 if/else 嵌套)都有效,因为它以我们指定条件的相同顺序执行,并且一旦出现 TRUE 条件它就会停止,即假设我们有多个条件
if(expr1) {
1
} else if(expr2) {
2
} else if(expr3) {
3
} else if(expr4) {
4
} else {
5}
首先检查第一个表达式 ('expr1'),然后检查第二个,依此类推。当它 return 为真时,它退出,即它是一个嵌套条件
if(expr1) {
1
} else {
if(expr2) {
2
} else {
if(expr3) {
3
} else {
if(expr4) {
4
} else 5
}
}
}
这样做是有代价的,即只要我们有更多的值匹配 1,就只执行 expr1 从而节省时间,但是如果有更多的 5 个值,那么所有这些条件都会被检查