让我尽量使这个问题尽可能笼统。
假设我有两个变量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中呢?
这看起来很简单(而且很可能是这样),但我已经很久没有让它起作用了。
发布于 2014-05-01 21:42:43
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 92) 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 93) 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修订了,增加了更多的解决方案。
发布于 2014-05-01 22:30:46
下面是一种更复杂的方法,使用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发布于 2014-05-01 21:49:07
数据帧版本,与上面的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
}
}https://stackoverflow.com/questions/23416899
复制相似问题