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

时间:2013-11-05 16:34:14

标签: r

我是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

感谢您的帮助!

3 个答案:

答案 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

==