在R数据框中创建布尔列,如果另一列的值逐行更改,则返回true

时间:2019-01-16 05:48:14

标签: r dplyr data-manipulation

标题有些罗word,但我的问题很难用一个摘要来解释,因此我准备了一个可复制的示例。以下是我的数据框的子集:

> zed
   possessionName possessionMarket
1          Eagles   Boston College
2     Blue Devils             Duke
3            <NA>             <NA>
4     Blue Devils             Duke
5          Eagles   Boston College
6     Blue Devils             Duke
7     Blue Devils             Duke
8          Eagles   Boston College
9          Eagles   Boston College
10         Eagles   Boston College
11           <NA>             <NA>
12    Blue Devils             Duke
13    Blue Devils             Duke
14           <NA>             <NA>
15         Eagles   Boston College

> dput(zed)
structure(list(possessionName = c("Eagles", "Blue Devils", NA, 
"Blue Devils", "Eagles", "Blue Devils", "Blue Devils", "Eagles", 
"Eagles", "Eagles", NA, "Blue Devils", "Blue Devils", NA, "Eagles"
), possessionMarket = c("Boston College", "Duke", NA, "Duke", 
"Boston College", "Duke", "Duke", "Boston College", "Boston College", 
"Boston College", NA, "Duke", "Duke", NA, "Boston College")), class = "data.frame", row.names = c(NA, 
15L))

这是我想要的输出:

> zed
   possessionName possessionMarket outputCol
1          Eagles   Boston College         1
2     Blue Devils             Duke         1
3            <NA>             <NA>         0
4     Blue Devils             Duke         0
5          Eagles   Boston College         1
6     Blue Devils             Duke         1
7     Blue Devils             Duke         0
8          Eagles   Boston College         1
9          Eagles   Boston College         0
10         Eagles   Boston College         0
11           <NA>             <NA>         0
12    Blue Devils             Duke         1
13    Blue Devils             Duke         0
14           <NA>             <NA>         0
15         Eagles   Boston College         1

问题:我希望newCol中的第一行为1。对于所有后续行,如果学校名称从一行到另一行。例如,第1行为== 1,第2行为Eagles,因此第2行在Blue Devils列中应为1。

如果存在一个,我希望该行为零。

请注意,尽管有NA,但在第2-4行中,学校名称没有变化,所以第4行newCol。但是,在第10-12行中,数据从Eagles到Blue Devils(尽管中间有一个NA),所以第12行应为1。

通常,我会按照以下方式做一些事情:

== 0

...但是由于NA的存在,这种方法被挫败了。我有更好的办法解决这个问题吗?我正在为此积极努力,希望在发布答案之前先发布答案,但可以使用一些帮助。提前致谢 !!!

2 个答案:

答案 0 :(得分:1)

一种方法是使用Error: Cannot find a relation to rewrite. 中的NA用先前的NA填充na.locf并进行比较

zoo

但是由于您使用的是library(zoo) zed$possessionName <- na.locf(zed$possessionName) zed$output_col <- c(1, +(zed$possessionName[-1] != zed$possessionName[-nrow(zed)])) zed # possessionName possessionMarket output_col #1 Eagles Boston College 1 #2 Blue Devils Duke 1 #3 Blue Devils <NA> 0 #4 Blue Devils Duke 0 #5 Eagles Boston College 1 #6 Blue Devils Duke 1 #7 Blue Devils Duke 0 #8 Eagles Boston College 1 #9 Eagles Boston College 0 #10 Eagles Boston College 0 #11 Eagles <NA> 0 #12 Blue Devils Duke 1 #13 Blue Devils Duke 0 #14 Blue Devils <NA> 0 #15 Eagles Boston College 1 ,所以我们可以使用tidyversefill

lag

答案 1 :(得分:0)

因此,这可以使用zoo程序包先去除NA,然后进行逐行偏移比较。

zed <- zed %>%
    dplyr::mutate(possIdTemp = zoo::na.locf(possessionName)) %>%
    dplyr::mutate(isNewPossession = c(1, ifelse(possIdTemp[2:length(possIdTemp)] != possIdTemp[1:(length(possIdTemp)-1)], 1, 0)))

请允许我寻求更好的解决方案,尤其是我不喜欢代码行c(1, ifelse(possIdTemp[2:length(possIdTemp)] != possIdTemp[1:(length(possIdTemp)-1)], 1, 0))-谢谢!