这是我的第一篇文章,所以我希望它不是太初级。我试图将具有负数量的观察值与具有正数量和等于绝对量(金额)的对应物进行匹配。此外,我想检查Amounts是否来自同一个账户。为此,我尝试使用for循环,但收到以下错误:“操作可能只适用于数字,逻辑或复杂类型。”到目前为止,这是我的代码:
for(i in 1:nrow(data)){
for(j in 1:nrow(data)){
if ((data$Amount[i]=abs(data$Amount[j]))&(data$Amount[i]!=data$Amount[j])&(data$Account[i]=data$Account[j]))
{data$debit[i]<-1}}}
有没有人知道为什么会这样,或者知道使用Apply函数系列的更好方法?提前谢谢!
编辑: 下面是一个玩具数据集:来说明这个例子。例如,在这个数据集上,我想创建一个指标变量,除了ID = 3外,该指标变量为0,因为对于观察,4.7 = abs(-4.7)和“abc1”=“abc1”。
Data <- " ID Amount Account
1 5.0 abc1
2 -5.0 abc9
3 4.7 abc1
4 4.6 abc7
5 5.0 abc8
6 -4.7 abc1 "
答案 0 :(得分:1)
您需要使用==
运算符(=
是一个赋值运算符)和&&
而不是&
运算符作为逻辑条件:
## Assignment (incorrect in this case!)
1 = 1
# Error in 1 = 1 : invalid (do_set) left-hand side to assignment
a <- 1
a = a
请注意,对于a = a
,没有进行逻辑检查(仅相当于a <- a
;请参阅更多here)。
## Checking equivalence (returns a logical)
1 == 1
# [1] TRUE
a == a
# [1] TRUE
对于&
和&&
之间的差异,第二个评估完整条件和第一个元素(请参阅here)。
检查data$Amount[i]
和data$Amount[j]
的总和是否为空而不是检查它们是否具有第一个绝对值但不是相同的有符号值可能更为优雅。
## Your example
for(i in 1:nrow(data)){
for(j in 1:nrow(data)){
if ( (sum(c(data$Amount[i], data$Amount[j])) == 0) && (data$Account[i] == data$Account[j]) ) {
data$debit[i]<-1
}
}
}
答案 1 :(得分:1)
这是一种使用更少代码实现相同结果的替代方法(我认为它也更容易阅读)
library(dplyr)
Data <- Data %>%
group_by(Account) %>%
mutate(
debit = (Amount > 0 & -Amount %in% unique(Amount)) * 1
) %>%
ungroup()
如果您不熟悉管道操作符(%>%
),它允许我们避免将许多函数嵌套在另一个中。它的工作原理是获取前一个函数的输出,并将其作为下一个函数的第一个参数输入。因此,此代码获取数据集(Data
),按Account
对其进行分组,添加具有所需标准的指示符变量的新列,然后取消组合数据,使其恢复为正常格式
循环在这些函数调用中完成,这允许它们以编译语言(通常是C ++)实现 - 这可以比R快很多。