替代循环ifelse()用于矢量数据

时间:2018-01-12 16:51:28

标签: r for-loop if-statement warnings

我有一个价格数据框dat和一个货币为cur的第二个数据框。我想要做的是将dat中的每个非欧元价格转换为欧元,其中for()函数和嵌套ifelse()else价格已经是欧元,该函数不应执行任何操作,并将原始值返回Price €中的dat列。

DAT:

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 { }
  }

输出应该是这样的:

DAT:

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€列中的NAs(这些是具有欧元货币的国家/地区) - 因为在else的情况下没有告诉函数该怎么做 - 来自{{{循环结束后1}}。

Price

DAT:

 index <- is.na(dat$Price€)
 dat$Price€[index] <- dat$Price[index]

我的问题是,R发出错误信息:

Nation  Price  Price€
AT      10     10
AT      12     12
BE      15     15
BG      30     15.3
BG      40     20.4
CZ      200    7.836

它的作用是将所有价格值乘以第一个汇率(0.51),然后停止为两个数据帧中的列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 查找相同的值以应用不同的汇率。这只是我的数据集中的一个简单示例。欧盟内每个国家/地区有多个条目(n = 1740)。

这听起来可能是一种复杂的方式,但我是R的新手,想知道如何修复这个函数或者替代函数是什么。

干杯

2 个答案:

答案 0 :(得分:1)

您的代码存在的问题是您正在将矢量与if (dat$Nation == cur$Nation[i])中的字符进行比较,因此错误告诉您它只会将dat$Nation的第一个元素与cur$Nation[i]进行比较

在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

希望这有帮助!

答案 1 :(得分:0)

我认为这将更容易作为合并/加入操作。使用整洁的诗句,你可以做到

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表中的国家的比率改为1.