我从 Stata 转到 R,有一个简单的语法问题,但我无法解决。我正在尝试循环多种货币(英镑欧元日元)以进行汇率调整。对于以上面列出的货币之一计价的每条记录,将“amount_usd”设置为等于“amount”除以汇率(USDGBP、USDEUR、USDJPY)。
创建数据:
df <- data.frame(currency = c("GBP", "GBP", "EUR", "EUR", "JPY"),
amount = c(100, 200, 100, 200, 100),
USDGBP = c(1.5, 1.5, 1.5, 1.5, 1.5),
USDEUR = c(1.1, 1.1, 1.1, 1.1, 1.1),
USDJPY = c(100, 100, 100, 100, 100))
df$amount_usd <- df$amount
我尝试了下面的各种版本的 for 循环,但没有任何运气。如果您能提供有关 (1) 正确的循环语法和 (2) 使代码更优雅的提示,我将不胜感激。
df$face_value_curr_usd <- df$face_value_curr
for (curr in c("GBP", "EUR", "JPY")) {
if (df[,which(colnames(df) == "currency")] == curr) {
df[,which(colnames(df) == "amount_usd")] <-
df[, which(colnames(df) == "amount")] / df[,which(colnames(df) == c("USD",curr))]
}
else {
}
}
生成的 df$amount_usd 应采用以下值:
c(66.67, 133.33, 90.91, 181.82, 1)
最佳答案
您真正想要的是矢量化操作而不是循环。这个想法是使用行索引对要修改的数据部分进行子集化,然后立即对其进行所有计算。
首先,您不需要以数字方式引用列。而不是
df[,which(colnames(df) == "currency")]
你可以直接使用
df[, "currency"]
或者是带有 $
运算符的别名
df$currency
您可以使用向量来识别数据框中的哪些行与给定值匹配
gbp_rows <- df$currency == "GBP"
您可以使用that仅将新值分配给这些行,例如
df$face_value_curr_usd[gbp_rows] <- df$amount[gbp_rows] / df$fxGBP[gbp_rows]
尽管我必须认为 fxGBP
是一个常数,对吗?那么也许这样的事情就可以了?
df$face_value_curr_usd[gbp_rows] <- df$amount[gbp_rows] / fxGBP
正如已评论的那样,您的问题的可重现版本会很有帮助,我不确定这是否是您想要做的。
编辑:现在我们有了 df
,结合了我所说的和 Cris 的答案:
df <- data.frame(currency = c("GBP", "GBP", "EUR", "EUR", "JPY"),
amount = c(100, 200, 100, 200, 100),
USDGBP = c(1.5, 1.5, 1.5, 1.5, 1.5),
USDEUR = c(1.1, 1.1, 1.1, 1.1, 1.1),
USDJPY = c(100, 100, 100, 100, 100))
for(curr in unique(df$currency)) {
this_curr_rows <- df$currency == curr
df$amount_usd[this_curr_rows] <- df$amount[this_curr_rows] / df[this_curr_rows, paste0("USD", curr)]
}
关于r - R 中 for 循环的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46696005/