%in,%=或其他来比较多个值

时间:2017-05-19 15:25:46

标签: r vector

我认为我仍然不清楚R在矢量化语句中如何处理单个元素。

我有以下代码

df1$flag <- ifelse(df1$year < 2013 &
        df1$year == df2$year &
        as.character(df1$code) == as.character(df2$code), 'Y', df1$flag)

我正在对此数据进行操作

year <- c(2011, 2012, 2011, 2013, 2014, 2016, 2016, 2015, 2016, 2010)
flag <- 'N'
code <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
df1 <- data.frame(year, flag, code)

rm(year)
rm(flag)
rm(code)

year <- c(2015, 2013, 2011, 2012, 2016, 2016, 2010)
code <- c(5, 7, 3, 2, 14, 99, 10)
df2 <- data.frame(year, code)

df1$flag <- ifelse(df1$year < 2013 &
                     df1$year == df2$year &
                     as.character(df1$code) == as.character(df2$code), 'Y', df1$flag)

我希望这是输出

> df1
   year flag code
1  2011    1    1
2  2012    Y    2
3  2011    Y    3
4  2013    1    4
5  2014    1    5
6  2016    1    6
7  2016    1    7
8  2015    1    8
9  2016    1    9
10 2010    Y   10

但相反,我得到了这个

> df1
   year flag code
1  2011    1    1
2  2012    1    2
3  2011    Y    3
4  2013    1    4
5  2014    1    5
6  2016    1    6
7  2016    1    7
8  2015    1    8
9  2016    1    9
10 2010    1   10

我希望ifelse语句将df1$yeardf1$code的每个元素与df2$yeardf2$code的每个元素进行比较,但它并不是==。看起来像%in%for(i in 1:nrow(df1)) { for(z in 1:nrow(df2)) { if(df1$year[i] < 2013 & df1$year[i] == df2$year[z] & as.character(df1$code[i]) == as.character(df2$code[z])) df1$flag[i] <- 'Y' } } 会这样做。

换句话说,我想要的是比较像这样的元素

for

显然像这样使用==会大大减慢执行速度并且无法使用,但它看起来不像%in%identical()all.equal()或{{ 1}}也将执行我在for循环中描述的内容。如何获得我在R?

中描述的输出

1 个答案:

答案 0 :(得分:1)

ifelse逐个元素地比较两个向量(假设它们具有相同的长度,如果没有,则小向量将被循环使用它们)。

这意味着你的代码:

df1$flag <- ifelse(df1$year < 2013 &
        df1$year == df2$year &
        as.character(df1$code) == as.character(df2$code), 'Y', df1$flag)

相当于:

for(i in 1:nrow(df1)) {
         if(df1$year[i] < 2013 & df1$year[i] == df2$year[i] & 
            as.character(df1$code[i]) == as.character(df2$code[i]))
           df1$flag[i] <- 'Y'
}

假设df1和df2具有相同的行数。

更新

这是merge而不是for loopif else的情况。基本上,您希望合并年份和代码上的数据集,然后如果年份小于2013年,则指定'Y'标记。

所以,我在df2中添加了一个标识符,如下所示:

year <- c(2015, 2013, 2011, 2012, 2016, 2016, 2010)
code <- c(5, 7, 3, 2, 14, 99, 10)
flag2 <- 'Y'
#make sure the flags are not factors
df2 <- data.frame(year, code, flag2, stringsAsFactors = FALSE)

然后你就这样做了:

#merge on year and code
newdf <- merge(df1, df2, by = c('year', 'code'), all.x = TRUE)
#assign Y to flag if year < 2013 and flag2 == Y
newdf$flag[newdf$year < 2013 & newdf$flag2 == 'Y'] <- 'Y'
#delete flag2
newdf$flag2 <- NULL
newdf

停止

   year code flag
1  2010   10    Y
2  2011    1    N
3  2011    3    Y
4  2012    2    Y
5  2013    4    N
6  2014    5    N
7  2015    8    N
8  2016    6    N
9  2016    7    N
10 2016    9    N