如果行和上一行符合要求,则将值分配给行

时间:2017-09-11 22:26:58

标签: r dataframe

这些是我的活动以及每个活动的X和Y坐标。如果事件= 0< 0,我希望将值“1”分配给事件。 x< 4& 0< y< 4和前一个事件= x> 4& y> 4,如果不符合标准,则指定值“0”。这是我的初始表:

Event    LocX    LocY
  1       6        6
  2       3        2
  3       3        7
  4       1        4
  5       7        4
  6       1        2
  7       8        5
  8       1        1

我的决赛桌看起来像是:

Event    LocX    LocY   Value 
  1       6        6      0
  2       3        2      1
  3       3        7      0
  4       1        4      0
  5       7        4      0
  6       1        2      1
  7       8        5      0
  8       1        1      1

任何帮助将不胜感激!

6 个答案:

答案 0 :(得分:3)

使用dplyr的{​​{1}}方式。我将数据框命名为ifelse

df1

答案 1 :(得分:1)

如果我的上述评论是正确的,以下内容将会这样做。

n <- nrow(dat)
log1 <- 0 < dat$LocX & dat$LocX < 4 & 0 < dat$LocY & dat$LocY < 4
log2 <- c(FALSE, c(dat$LocX[-n] > 4 & dat$LocY[-n] > 4))
dat$Value <- as.integer(log1 & log2)
dat
#  Event LocX LocY Value
#1     1    6    6     0
#2     2    3    2     1
#3     3    3    7     0
#4     4    1    4     0
#5     5    7    4     0
#6     6    1    2     0
#7     7    8    5     0
#8     8    1    1     1

数据:

dat <-
structure(list(Event = 1:8, LocX = c(6L, 3L, 3L, 1L, 7L, 1L, 
8L, 1L), LocY = c(6L, 2L, 7L, 4L, 4L, 2L, 5L, 1L)), .Names = c("Event", 
"LocX", "LocY"), class = "data.frame", row.names = c(NA, -8L))

答案 2 :(得分:1)

这是一种方式:

#Data table version:
df$Value <- 0
df[intersect(which(LocX>4&LocY>4)+1,which(LocX>0&LocX<4&LocY>0&LocY<4)),"Value"]<-1

#Data frame version:
df$Value <- 0
df[with(df,intersect(which(LocX>4&LocY>4)+1,which(LocX>0&LocX<4&LocY>0&LocY<4))),]<-1

输出:

   Event LocX LocY Value
1:     1    6    6     0
2:     2    3    2     1
3:     3    3    7     0
4:     4    1    4     0
5:     5    7    4     0
6:     6    1    2     0
7:     7    8    5     0
8:     8    1    1     1

示例数据:

require(data.table)

df <- fread("Event   LocX     LocY
             1       6        6
             2       3        2
             3       3        7
             4       1        4
             5       7        4
             6       1        2
             7       8        5
             8       1        1")

答案 3 :(得分:1)

只是为了表明将一大堆逻辑条件放在基础R中也不是一个大问题。只需创建一个列表,然后使用&递归地将它们与Reduce(和)运算符组合在一起。这与dplyr case_when内部所做的非常相似:

Reduce(`&`, with(dat, 
  list(
    LocX > 0, 
    LocX < 4, 
    LocY > 0, 
    LocY < 4, 
    c(FALSE, head(LocX,-1) > 4), 
    c(FALSE, head(LocY,-1) > 4) 
  )
))
#[1] FALSE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE

答案 4 :(得分:1)

另一种cellForRow方法。它就像使用@IBAction函数比较前一个值时neilfws的dplyr方法的翻译。

data.table

数据

shift

答案 5 :(得分:0)

我有这个for循环,它将产生所需的输出。

for(i in 1:nrow(df)){
  df$Value[i] = 0
  if(i > 1){
    if(df$LocX[i] < 4 & df$LocY[i] < 4 & df$LocX[i-1] > 4 & df$LocY[i-1] > 4){
      df$Value[i] = 1
    }
  }
}