Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 与数据帧中最近的非NA值的距离_R_Dataframe - Fatal编程技术网

R 与数据帧中最近的非NA值的距离

R 与数据帧中最近的非NA值的距离,r,dataframe,R,Dataframe,我有下面的dataframe df,我想为每一行添加一列,其中包含与最近的非NA值之间的距离 df <- data.frame(x = 1:20) df[c(1, 3, 4, 5, 11, 14, 15, 16), "x"] <- NA df让x成为包含NA的向量,你的问题是 a <- which(!is.na(x)) b <- which(is.na(x)) 如果它很长并且outer的内存使用成了问题,我们可能会这样做 distance <- numeric

我有下面的dataframe df,我想为每一行添加一列,其中包含与最近的非NA值之间的距离

df <- data.frame(x = 1:20)
df[c(1, 3, 4, 5, 11, 14, 15, 16), "x"] <-  NA

df让
x
成为包含
NA
的向量,你的问题是

a <- which(!is.na(x))
b <- which(is.na(x))
如果它很长并且
outer
的内存使用成了问题,我们可能会这样做

distance <- numeric(length(x))
distance[is.na(x)] <- sapply(b, function (bi) min(abs(bi - a)))

distance这里是另一种使用
rle
rank
的方法:

library(dplyr)
library(magrittr)

df <- data.frame(x=seq(1, 20))
df[c("1", "3", "4", "5", "11", "14", "15", "16"), 1] <-  NA

rle.len <- df$x %>% is.na %>% rle %$% lengths

df %>% 
  mutate(na.seq=rle.len %>% seq_along %>% rep(rle.len)) %>% 
  group_by(na.seq) %>%
  mutate(distance=ifelse(is.na(x), pmin(rank(na.seq, ties.method = "first"),
                                        rank(na.seq, ties.method = "last")), 0))

    x na.seq distance
1  NA      1        1
2   2      2        0
3  NA      3        1
4  NA      3        2
5  NA      3        1
库(dplyr)
图书馆(magrittr)
df%
变异(na.seq=rle.len%%>%seq_沿%>%rep(rle.len))%%>%
分组依据(不适用序号)%>%
突变(距离=ifelse(is.na(x),pmin(秩(na.seq,ties.method=“first”),
排名(na.seq,ties.method=“last”)),0)
x na.seq距离
1 NA 11
2   2      2        0
3 NA 3 1
4 NA 3 2
5 NA 3 1

您可以使用
findInterval
。首先,找到
NA
非NA
值的索引,并初始化距离列:

na <- which(is.na(df$x))
non_na <- which(!is.na(df$x))
df$distance2 <- 0
一种方法是在使用包将矩阵转换为光栅层对象后,在包中使用

该软件包适用于地图,因此当您使用
光栅()
时,对象将具有单位、分辨率等。因此,当您使用
距离()
时,对于与非NA(我是15796.35)相距一米的元素,距离可能非常大。只需除以这个数量(由于舍入错误,可能是
round()
)就可以得到你的答案

例如,如果我有一个名为
a1
的NAs数组对象:

> a1 = array(
    c(
       c(1, 5, 6, NA, 1, 2, 5),
       c(3, 4, NA, NA, NA, 8, 1),
       c(5, 1, 7, NA, 2, 3, 7),
       c(8, 1, 1, 2, 3, 6, 2)
     ),
    c(7, 4)
  )
> r1 = raster(a1)
> d1 = distance(r1)
> as.matrix(d1)    

         [,1]     [,2]     [,3] [,4]
[1,]     0.00     0.00     0.00    0
[2,]     0.00     0.00     0.00    0
[3,]     0.00 15796.35     0.00    0
[4,] 15796.33 31592.66 15796.33    0
[5,]     0.00 15796.33     0.00    0
[6,]     0.00     0.00     0.00    0
[7,]     0.00     0.00     0.00    0

> round(
     as.matrix(d1) / 15796.35,
     0
  )

     [,1] [,2] [,3] [,4]
[1,]    0    0    0    0
[2,]    0    0    0    0
[3,]    0    1    0    0
[4,]    1    2    1    0
[5,]    0    1    0    0
[6,]    0    0    0    0
[7,]    0    0    0    0
这是你的答案。不过,我不知道
distance()
函数背后的代码有多高效,所以我不知道这是否需要一段时间


编辑:在具有29000 NAs的阵列对象上进行测试,需要很长时间。我建议您只对NAs较少的对象使用此选项。

我有20000行。应该很好,谢谢。我刚刚注意到,对于在最后一行中使用NAs完成数据帧的情况,您的方法将不起作用。它将考虑从非NA值的距离为1的最后一行(NA)。
na <- which(is.na(df$x))
non_na <- which(!is.na(df$x))
df$distance2 <- 0
df$distance2[na] <- abs(na - non_na[findInterval(na, (non_na[-length(non_na)] + non_na[-1]) / 2) + 1])

df
#     x distance distance2
# 1  NA        1         1
# 2   2        0         0
# 3  NA        1         1
# 4  NA        2         2
# 5  NA        1         1
# 6   6        0         0
# 7   7        0         0
# 8   8        0         0
# 9   9        0         0
# 10 10        0         0
# 11 NA        1         1
# 12 12        0         0
# 13 13        0         0
# 14 NA        1         1
# 15 NA        2         2
# 16 NA        1         1
# 17 17        0         0
# 18 18        0         0
# 19 19        0         0
# 20 20        0         0
> a1 = array(
    c(
       c(1, 5, 6, NA, 1, 2, 5),
       c(3, 4, NA, NA, NA, 8, 1),
       c(5, 1, 7, NA, 2, 3, 7),
       c(8, 1, 1, 2, 3, 6, 2)
     ),
    c(7, 4)
  )
> r1 = raster(a1)
> d1 = distance(r1)
> as.matrix(d1)    

         [,1]     [,2]     [,3] [,4]
[1,]     0.00     0.00     0.00    0
[2,]     0.00     0.00     0.00    0
[3,]     0.00 15796.35     0.00    0
[4,] 15796.33 31592.66 15796.33    0
[5,]     0.00 15796.33     0.00    0
[6,]     0.00     0.00     0.00    0
[7,]     0.00     0.00     0.00    0

> round(
     as.matrix(d1) / 15796.35,
     0
  )

     [,1] [,2] [,3] [,4]
[1,]    0    0    0    0
[2,]    0    0    0    0
[3,]    0    1    0    0
[4,]    1    2    1    0
[5,]    0    1    0    0
[6,]    0    0    0    0
[7,]    0    0    0    0