我是R的初学者。虽然我已经在手册中阅读了很多内容,但在这个板上,我不得不问我的第一个问题。它与here有点相同但不完全相同,我不明白那里的解释。
我有一个包含数十万行和30列的数据帧。但是对于我的问题,我创建了一个可以使用的简化数据框:
a <- sample(c(1,3,5,9), 20, replace = TRUE)
b <- sample(c(1,NA), 20, replace = TRUE)
df <- data.frame(a,b)
现在我想比较最后一列的值(这里是列b
),这样我就可以迭代地查看每一行的值,如果它与下一行中的相同。如果它是相同的,我想在同一行的新列中写入0
作为值,否则它应该是1
作为新列的值。
在这里,您可以看到我的代码无效,因为新列的行只包含0
:
m<-c()
for (i in seq(along=df[,1])){
ifelse(df$b[i] == df$b[i+1],m <- 0, m <- 1)
df$mov <- m
}
结果,我想得到的,看起来像下面的例子。怎么了?还有比创建循环更好的方法吗?对我的大数据集来说,循环可能非常慢。
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
感谢您的帮助!
答案 0 :(得分:1)
您可以执行以下操作来标记匹配
的内容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)
此处有很多NA
,因为您的列NA
中有很多b
个,与NA
的任何比较都会返回NA
而不是TRUE/FALSE
。您可以添加df[is.na(df$bnextsame),"bnextsame"] <- 0
来修复该问题。
答案 1 :(得分:1)
您的示例中有几点需要考虑。
首先,为了避免循环,您可以创建一个位移的向量副本。 (大约有20种方法可以做到这一点。)然后当你测试向量B
vs C
时,它将逐个元素地比较每个位置与其邻居。
其次,平等比较不适用于NA - 它们总是返回NA。所以NA == NA
不是TRUE
它是NA
!同样,大约有20种方法可以解决这个问题,但是在这里我刚刚用临时替换中的所有NA
替换了一个占位符,该占位符将用于相等的测试。
最后,您必须决定要对最后一个值(没有邻居)做什么。在这里,我放了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
答案 2 :(得分:0)
您可以对zoo
的{{1}}使用“滚动平等测试”。此外,rollapply
优先于identical
。
==