R-比较列中的值,并使用此比较的结果创建一个新列。有比循环更好的方法吗?
我是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) 结果,我想要得到的,看起来像下面
我有一个包含数十万行和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
vsC
时,它会对每个位置和相邻位置进行逐元素比较
其次,平等性比较不适用于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 Useset.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