【发布时间】:2017-12-08 11:40:51
【问题描述】:
一个可能的重复是here,但它对我没有帮助。我的情况可能不同。
考虑一个示例 data.table。
set.seed(21)
DT <- data.table(col1=sample(x=1:10,size = 5),col2=sample(x=10:20,size=5))
DT
col1 col2
1: 8 20
2: 3 11
3: 6 19
4: 2 17
5: 10 15
并考虑一个函数check 我想应用于每一行:
check <- function(x,y) if ((y-x)>10) "A" else "B"
现在,如果我通过在DT 的j 部分调用函数check 来运行此分配,它会惨遭失败,
DT[,state:=check(col1,col2)]
并抛出此警告
Warning message:
In if ((y - x) > 10) "A" else "B" :
the condition has length > 1 and only the first element will be used
显然,我猜 data.table 一次处理整个向量并且函数需要一个值,所以我认为最后一个值是向量中的当前值,所以我做了这个更改,这似乎是另一个愚蠢的举动:-)
DT[,state:=check(last(col1),last(col2))]
DT
col1 col2 state
1: 8 20 B
2: 3 11 B
3: 6 19 B
4: 2 17 B
5: 10 15 B
我看到 check() 函数是针对最后一个值计算的,并且每次都会覆盖所有以前的值。我想要的是这个输出:
DT
col1 col2 state
1: 8 20 A
2: 3 11 A
3: 6 19 A
4: 2 17 A
5: 10 15 B
那么如何让函数调用在 data.table 中为每一行独立工作?
实际功能:
在我收到 akrun 的建议后,使用 ifelse,它适用于像 check() 这样的简单条件,但我这里有一个稍微复杂的功能。所以请将check替换为allowed_state
allowed_state <- function(old=NULL,new=NULL){
legalst<-data.table(from=c(1,1,9,9,7,8,7,10,10,11,11,10,11,8,7),to=c(11,7,10,7,8,7,9,9,7,1,7,1,7,9,10)) # all legal state transitions for a user
if(new %in% legalst[from==old,to]) "Legal" else "Illegal state change"
}
【问题讨论】:
-
你需要
ifelse而不是if/else即check <- function(x,y) ifelse((y-x)>10, "A", "B") -
实际上,我的实际函数
check转换为ifelse 并不是那么简单。除非您可以建议一种转换方法。让我在问题中添加我的实际功能。 -
会有帮助的
-
@akrun 你能查一下实际的功能(添加),现在让我们看看如何应用
ifelse。我试过了,但是关于向量的大小有不同的警告。它对legalst[from==old,to]部分不满意。
标签: r data.table