矢量数据循环 ifelse() 的替代方法
Alternative to loop ifelse() for vector data
我有一个价格数据框 dat
和第二个包含货币的数据框 cur
。我想要做的是使用 for()
函数和嵌套 ifelse()
将 dat
中的每个非欧元价格转换为欧元。 else
价格已经是欧元,该函数应该什么都不做,并且 return 原始值进入 dat
中的列 Price €
。
数据:
Nation Price Price€
AT 10
AT 12
BE 15
BG 30
BG 40
CZ 200
cur:
Nation Rate
BG 0.51
CZ 0.03918
cur
中仅包含使用非欧盟货币的国家/地区。
我使用了这段代码:
for (i in 1:length(cur)){
if(dat$Nation == cur$Nation[i]){
dat$Price * cur$Rate[i]
}
else { }
}
输出应该是这样的:
数据:
Nation Price Price€
AT 10 NA
AT 12 NA
BE 15 NA
BG 30 15.3
BG 40 20.4
CZ 200 7.836
我们的想法是在 Price€
列中填充 NA(这些国家/地区使用欧元货币) - 由于没有告诉函数在 else
的情况下要做什么 - 值来自Price
循环结束后。
index <- is.na(dat$Price€)
dat$Price€[index] <- dat$Price[index]
数据:
Nation Price Price€
AT 10 10
AT 12 12
BE 15 15
BG 30 15.3
BG 40 20.4
CZ 200 7.836
我的问题是,R 给出错误信息:
Warning messages:
1: In if (dat$Nation == cur$Nation[i]) { :
the condition has length > 1 and only the first element will be used
2: In if (dat$Nation == cur$Nation[i]) { :
the condition has length > 1 and only the first element will be used
它所做的是将所有价格值乘以第一个汇率 (0.51),然后停下来寻找两个数据框中 Nation
列的相同值以应用不同的汇率。这只是我的数据集中的一个简单示例。欧盟 (n=1740) 内的每个国家/地区都有多个条目。
这听起来可能是一种复杂的方法,但我是 R 的新手,想知道如何修复此功能或替代功能是什么。
干杯
你的代码的问题是你正在比较向量和 if (dat$Nation == cur$Nation[i])
中的字符,所以错误告诉你它只会比较 dat$Nation
和 [=14] 的第一个元素=].
在 R 中,for 循环通常不是必需的(而且很慢)。例如,您可以执行以下操作:
dat$conv <- cur$Rate[match(dat$Nation,cur$Nation)] # add the conversion factor
dat$PriceE <- ifelse(is.na(dat$conv), dat$Price, dat$Price * dat$conv)
dat$conv <- NULL
输出:
Nation Price PriceE
1 AT 10 10.000
2 AT 12 12.000
3 BE 15 15.000
4 BG 30 15.300
5 BG 40 20.400
6 CZ 200 7.836
希望对您有所帮助!
我认为这作为 merge/join 操作会容易得多。使用整洁的诗句你可以做到
library(tidyverse)
dat <- read_table("Nation Price
AT 10
AT 12
BE 15
BG 30
BG 40
CZ 200")
cur <- read_table("Nation Rate
BG 0.51
CZ 0.03918")
dat %>% left_join(cur) %>%
mutate(Rate=coalesce(Rate, 1)) %>%
mutate(EPrice = Price * Rate)
这里唯一的技巧是将不在 cur
table 中的那些国家的汇率更改为 1。
我有一个价格数据框 dat
和第二个包含货币的数据框 cur
。我想要做的是使用 for()
函数和嵌套 ifelse()
将 dat
中的每个非欧元价格转换为欧元。 else
价格已经是欧元,该函数应该什么都不做,并且 return 原始值进入 dat
中的列 Price €
。
数据:
Nation Price Price€
AT 10
AT 12
BE 15
BG 30
BG 40
CZ 200
cur:
Nation Rate
BG 0.51
CZ 0.03918
cur
中仅包含使用非欧盟货币的国家/地区。
我使用了这段代码:
for (i in 1:length(cur)){
if(dat$Nation == cur$Nation[i]){
dat$Price * cur$Rate[i]
}
else { }
}
输出应该是这样的:
数据:
Nation Price Price€
AT 10 NA
AT 12 NA
BE 15 NA
BG 30 15.3
BG 40 20.4
CZ 200 7.836
我们的想法是在 Price€
列中填充 NA(这些国家/地区使用欧元货币) - 由于没有告诉函数在 else
的情况下要做什么 - 值来自Price
循环结束后。
index <- is.na(dat$Price€)
dat$Price€[index] <- dat$Price[index]
数据:
Nation Price Price€
AT 10 10
AT 12 12
BE 15 15
BG 30 15.3
BG 40 20.4
CZ 200 7.836
我的问题是,R 给出错误信息:
Warning messages:
1: In if (dat$Nation == cur$Nation[i]) { :
the condition has length > 1 and only the first element will be used
2: In if (dat$Nation == cur$Nation[i]) { :
the condition has length > 1 and only the first element will be used
它所做的是将所有价格值乘以第一个汇率 (0.51),然后停下来寻找两个数据框中 Nation
列的相同值以应用不同的汇率。这只是我的数据集中的一个简单示例。欧盟 (n=1740) 内的每个国家/地区都有多个条目。
这听起来可能是一种复杂的方法,但我是 R 的新手,想知道如何修复此功能或替代功能是什么。
干杯
你的代码的问题是你正在比较向量和 if (dat$Nation == cur$Nation[i])
中的字符,所以错误告诉你它只会比较 dat$Nation
和 [=14] 的第一个元素=].
在 R 中,for 循环通常不是必需的(而且很慢)。例如,您可以执行以下操作:
dat$conv <- cur$Rate[match(dat$Nation,cur$Nation)] # add the conversion factor
dat$PriceE <- ifelse(is.na(dat$conv), dat$Price, dat$Price * dat$conv)
dat$conv <- NULL
输出:
Nation Price PriceE
1 AT 10 10.000
2 AT 12 12.000
3 BE 15 15.000
4 BG 30 15.300
5 BG 40 20.400
6 CZ 200 7.836
希望对您有所帮助!
我认为这作为 merge/join 操作会容易得多。使用整洁的诗句你可以做到
library(tidyverse)
dat <- read_table("Nation Price
AT 10
AT 12
BE 15
BG 30
BG 40
CZ 200")
cur <- read_table("Nation Rate
BG 0.51
CZ 0.03918")
dat %>% left_join(cur) %>%
mutate(Rate=coalesce(Rate, 1)) %>%
mutate(EPrice = Price * Rate)
这里唯一的技巧是将不在 cur
table 中的那些国家的汇率更改为 1。