如何将缺失值压入矢量

时间:2014-05-01 21:25:45

标签: r

让我试着让这个问题尽可能一般。

我们说我有两个变量 a b

a <- as.integer(runif(20, min = 0, max = 10))
a <- as.data.frame(a)
b <- as.data.frame(a[c(-7, -11, -15),])

所以 b 有17个观测值,是 a 的子集,有20个观测值。

我的问题如下:我将如何使用这两个变量来生成第三个变量 c ,其中 a 有20个观察值,但观察结果为7,11和缺少15个,其他观察结果与 b 相同但按 a 的顺序?

或者说有点不同:我怎样才能将这些缺失的观察结果插入位置7,11和15的变量 b

这看起来非常简单(而且可能是这样)但是我现在已经没有让它工作太久了。

3 个答案:

答案 0 :(得分:5)

1)循环试试这个循环:

# test data
set.seed(123) # for reproducibility
a <- as.integer(runif(20, min = 0, max = 10))
a <- as.data.frame(a)
b <- as.data.frame(a[c(-7, -11, -15),])

# lets work with vectors
A <- a[[1]]
B <- b[[1]]

j <- 1
C <- A
for(i in seq_along(A)) if (A[i] == B[j]) j <- j+1 else C[i] <- NA

给出:

> C
 [1]  2  7  4  8  9  0 NA  8  5  4 NA  4  6  5 NA  8  2  0  3  9

2)Reduce 这是一个无循环版本:

f <- function(j, a) j + (a == B[j])
r <- Reduce(f, A, acc = TRUE)
ifelse(duplicated(r), NA, A)

,并提供:

[1]  2  7  4  8  9  0 NA  8  5  4 NA  4  6  5 NA  8  2  0  3  9

3)dtw 。在相同名称的包中使用dtw,我们可以得到一个紧凑的无循环单行:

library(dtw)

ifelse(duplicated(dtw(A, B)$index2), NA, A)

,并提供:

[1]  2  7  4  8  9  0 NA  8  5  4 NA  4  6  5 NA  8  2  0  3  9

已修订已添加其他解决方案。

答案 1 :(得分:3)

这是一种更复杂的方法,使用Levenshtein距离算法,可以更好地处理更复杂的例子(在我尝试的几个较大的测试中它似乎也更快):

# using same data as G. Grothendieck:
set.seed(123) # for reproducibility
a <- as.integer(runif(20, min = 0, max = 10))
a <- as.data.frame(a)
b <- as.data.frame(a[c(-7, -11, -15),])
A = a[[1]]
B = b[[1]]

# compute the transformation between the two, assigning infinite weight to 
# insertion and substitution
# using +1 here because the integers fed to intToUtf8 have to be larger than 0
# could also adjust the range more dynamically based on A and B
transf = attr(adist(intToUtf8(A+1), intToUtf8(B+1),
                    costs = c(Inf,1,Inf), counts = TRUE), 'trafos')

C = A
C[substring(transf, 1:nchar(transf), 1:nchar(transf)) == "D"] <- NA
#[1]  2  7  4  8  9  0 NA  8  5  4 NA  4  6  5 NA  8  2  0  3  9

更复杂的匹配示例(贪婪算法执行效果不佳):

A = c(1,1,2,2,1,1,1,2,2,2)
B = c(1,1,1,2,2,2)

transf = attr(adist(intToUtf8(A), intToUtf8(B),
                    costs = c(Inf,1,Inf), counts = TRUE), 'trafos')

C = A
C[substring(transf, 1:nchar(transf), 1:nchar(transf)) == "D"] <- NA
#[1] NA NA NA NA  1  1  1  2  2  2

# the greedy algorithm would return this instead:
#[1]  1  1 NA NA  1 NA NA  2  2  2

答案 2 :(得分:2)

数据框版本,与上面的G不完全不同。 (假设a,b设置如上)。

j <- 1
c <- a
for (i in (seq_along(a[,1]))) {
    if (a[i,1]==b[j,1]) {
        j <- j+1
        } else 
        {
        c[i,1] <- NA
        }

}