我想应用一个给定的函数" passFailFunc"在我的dataFrame的给定列上。 这是一个例子:
df <- data.frame(A = letters[1:10], B = sample(1:20, 10))
=>
A B
1 a 7
2 b 15
3 c 4
4 d 9
5 e 17
6 f 8
7 g 18
8 h 14
9 i 16
10 j 12
和功能定义
passFailFunc <- function(x, th) {
if (x>th) {
status='fail'
} else {
status='pass'
}
status
}
我想创建一个新列&#34; status&#34;其中B列的数字被认为是&#39;通过&#39;如果它们低于阈值,则说th = 15,否则
df$status <- lapply(df$B, function(x) passFailFunc(x, 15))
=>
A B status
1 a 7 pass
2 b 15 pass
3 c 4 pass
4 d 9 pass
5 e 17 fail
6 f 8 pass
7 g 18 fail
8 h 14 pass
9 i 16 fail
10 j 12 pass
这很好,似乎在做这项工作。但是,当我尝试:
factor(df$status)
Error in sort.list(y) : 'x' must be atomic for 'sort.list'
Have you called 'sort' on a list?
状态列实际上是一个向量
> is.vector(df$status)
[1] TRUE
问题:如何正确生成&#39;状态&#39;专栏?
答案 0 :(得分:2)
lapply
只是一个漂亮的for
循环,尝试在R中避免使用它们总是更好。您的特定函数可以使用ifelse
df$status <- ifelse(df$B > 15, "fail", "pass")
如果您仍然希望将其用作功能,则可以尝试使用data.table
包
passFailFunc <- function(x, th) {
ifelse (x > th, "fail", "pass")
}
library(data.table)
setDT(df)[, status := lapply(.SD, function(x) passFailFunc(x, 15)), .SDcols = "B"]
factor(df$status)
对您不起作用的原因是因为lapply
返回了一个列表(阅读?lapply
文档),您可以使用str(df)
查看它。如果您仍想以原始方式执行此操作,请使用sapply
代替lapply
。
is.vector(df$status)
返回TRUE
的原因是因为list
是R中的向量。
尝试运行
is.vector(list(a=1))
## [1] TRUE
答案 1 :(得分:1)
您可以通过以下方式避免错误:
set.seed(1)
df <- data.frame(A = letters[1:10], B = sample(1:20, 10))
使用您的passFailFunc
df$status <- unlist(lapply(df$B, function(x) passFailFunc(x, 15)))
factor(df$status)
#[1] pass pass pass fail pass pass pass pass fail pass
#Levels: fail pass
或
factor(df$B<=15, labels=c('fail', 'pass'))
#[1] pass pass pass fail pass pass pass pass fail pass
#Levels: fail pass
或
c('pass', 'fail')[(df$B>15) +1]
#[1] "pass" "pass" "pass" "fail" "pass" "pass" "pass" "pass" "fail" "pass"