R-比较列中的值,并使用此比较的结果创建一个新列。有比循环更好的方法吗?

R-比较列中的值,并使用此比较的结果创建一个新列。有比循环更好的方法吗?,r,R,我是R的初学者。虽然我已经在手册中读了很多,在这个委员会上,我必须问我的第一个问题。它与有点相同,但实际上并不相同,我不理解其中的解释。我有一个包含数十万行和30列的数据帧。但对于我的问题,我创建了一个更简单的数据框架,您可以使用: a <- sample(c(1,3,5,9), 20, replace = TRUE) b <- sample(c(1,NA), 20, replace = TRUE) df <- data.frame(a,b) 结果,我想要得到的,看起来像下面

我是R的初学者。虽然我已经在手册中读了很多,在这个委员会上,我必须问我的第一个问题。它与有点相同,但实际上并不相同,我不理解其中的解释。
我有一个包含数十万行和30列的数据帧。但对于我的问题,我创建了一个更简单的数据框架,您可以使用:

a <- sample(c(1,3,5,9), 20, replace = TRUE)
b <- sample(c(1,NA), 20, replace = TRUE)
df <- data.frame(a,b)
结果,我想要得到的,看起来像下面的例子。怎么了?还有比创建循环更好的方法吗?对于我的大数据集,循环可能会非常慢

   a  b mov
1  9 NA   0
2  1 NA   1
3  1  1   1
4  5 NA   0
5  1 NA   0
6  3 NA   0
7  3 NA   1
8  5  1   0
9  1  1   0
10 3  1   0
11 1  1   0
12 9  1   0
13 1  1   1
14 5 NA   0
15 9 NA   0
16 9 NA   0
17 9 NA   0
18 5 NA   0
19 3 NA   0
20 1 NA   0

谢谢你的帮助

您可以这样做来标记匹配的

df$bnext <- c(tail(df$b,-1),NA)
df$bnextsame <- ifelse(df$bnext == df$b | (is.na(df$b) & is.na(df$bnext)),0,1)

<代码> df$bNest在你的例子中有两件事需要考虑。

首先,为了避免循环,可以创建向量的副本,该副本移动一个位置。(有大约20种方法可以做到这一点。)然后,当你测试向量
B
vs
C
时,它会对每个位置和相邻位置进行逐元素比较

其次,平等性比较不适用于NA——它们总是返回NA。所以
NA==NA
不是
TRUE
而是
NA
!同样,有大约20种方法可以解决这个问题,但在这里,我刚刚用一个占位符替换了临时向量中的所有
NA
s,该占位符将用于平等性测试

最后,您必须决定如何处理最后一个值(它没有邻居)。在这里我放置了
1
,这是您为“与其邻居不匹配”分配的任务

因此,根据
b
中可能的值范围,您可以执行以下操作

c = df$b 
z = length(c)
c[is.na(c)] = 'x'   # replace NA with value that will allow equality test
df$mov = c(1 * !(c[1:z-1] == c[2:z]),1)     # add 1 to the end for the last value
您可以对
zoo
rollapply
使用“滚动相等测试”。而且,
相同的
=
更可取

#identical(NA, NA)
#[1] TRUE
#NA == NA
#[1] NA

library(zoo)

df$mov <- c(rollapply(df$b, width = 2, 
        FUN = function(x) as.numeric(!identical(x[1], x[2]))), "no_comparison")
      #`!` because you want `0` as `TRUE` ;
      #I added a "no_comparison" to last value as it is not compared with any one
df
#   a  b           mov
#1  5  1             0
#2  1  1             0
#3  9  1             1
#4  5 NA             1
#5  9  1             1
#.....
#19 1 NA             0
#20 1 NA no_comparison
#相同(不适用,不适用)
#[1] 真的
#NA==NA
#[1] NA
图书馆(动物园)

df$mov Use
set.seed
当使用
sample
时,if-else的使用很好,但这对两个连续的NAs不起作用,因为该比较总是返回
NA
。此外,OP希望零作为相同值的代码,而不是1。谢谢!我得到了它!“0和1的结果改变了,但这与我的分析无关。你是对的,@beroe。”。我会在
ifelse
中添加另一个条件来检查两列是否都是
NA
@Simon1723,太好了。我做了编辑,以符合你的问题。祝你好运。嗨,也谢谢你,这也行。这是一个微不足道的问题,我只能“接受”一个答案。但你更接近我的问题,所以你得到了认可。
#identical(NA, NA)
#[1] TRUE
#NA == NA
#[1] NA

library(zoo)

df$mov <- c(rollapply(df$b, width = 2, 
        FUN = function(x) as.numeric(!identical(x[1], x[2]))), "no_comparison")
      #`!` because you want `0` as `TRUE` ;
      #I added a "no_comparison" to last value as it is not compared with any one
df
#   a  b           mov
#1  5  1             0
#2  1  1             0
#3  9  1             1
#4  5 NA             1
#5  9  1             1
#.....
#19 1 NA             0
#20 1 NA no_comparison