Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/65.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 填充数据框中缺少的值_R_Dplyr_Na_Missing Data_Tidyr - Fatal编程技术网

R 填充数据框中缺少的值

R 填充数据框中缺少的值,r,dplyr,na,missing-data,tidyr,R,Dplyr,Na,Missing Data,Tidyr,嘿,我需要填写数据框中缺少的值。逻辑很简单,如果M[i,j+1]中有值,则使用M[i,j+1],否则使用M[i,j-1]。但棘手的是,我需要为每一行填写从行的开头到最后一个非na值之后的列中缺少的值,而不仅仅是非空单元格附近的单元格 这是数据 a1 <- c('a',9,8,rep(NA,5)) a2 <- c('b',NA,NA,NA,NA,3,NA,4) a3 <- c('c',11,6,7,NA,NA,NA,6) M <- rbind(a1,a2,a3) ind &

嘿,我需要填写数据框中缺少的值。逻辑很简单,如果
M[i,j+1]
中有值,则使用
M[i,j+1]
,否则使用
M[i,j-1]
。但棘手的是,我需要为每一行填写从行的开头到最后一个非na值之后的列中缺少的值,而不仅仅是非空单元格附近的单元格

这是数据

a1 <- c('a',9,8,rep(NA,5))
a2 <- c('b',NA,NA,NA,NA,3,NA,4)
a3 <- c('c',11,6,7,NA,NA,NA,6)
M <- rbind(a1,a2,a3)
ind <- !is.na(M[,-1]) 
t <- tapply(M[,-1][ind], row(M[,-1])[ind], head, 1) 

M <- M %>%
 as.data.frame(stringsAsFactors = FALSE) %>%
 group_by(V1) %>%
 do(mutate(., last_non_na_col = max(apply(.,1,function(x) max(which(!is.na(x)))))))


 for (i in 1:nrow(M)) {         
  for (j in 3:(M$last_non_na_col[i]+1)) {      
    if (is.na(M[i,j])) { 
   M[i,j] = ifelse(!is.na(M[i,j+1]),M[i,j+1],(ifelse(!is.na(M[i,j-1]),M[i,j-1],t[i])))
 } }
 for (j in 2) { M[i,j] = ifelse(is.na(M[i,j]), M[i,j+1], M[i,j])}   
我的代码输出如下,这是正确的。请注意,对于单元格M[2,5],填充值应为7(之前的数字),而不是6(之后最近的数字)

V1 V2 V3 V4 V5 V6 V7 V8最后一列
1 a 9 8 NA NA 3
2 b 3 3 3 4 8
3 c 11 6 7 7 6 8
我这样做是为了循环。有人能帮我在tidyverse做这件事吗

谢谢


Cathy

由于我们有一个
tbl_df
,我们可以使用
tidyverse
方法

library(tidyverse)
gather(M, key, val, -V1) %>%
     group_by(V1) %>%
     fill(val, .direction = 'up') %>% 
     mutate(val = replace(val, which(is.na(val))[1], 
                         val[tail(which(!is.na(val)), 1)])) %>% 
    spread(key, val)
# A tibble: 3 x 8
# Groups:   V1 [3]
#  V1    V2    V3    V4    V5    V6    V7    V8   
#  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 a     9     8     8     NA    NA    NA    NA   
#2 b     3     3     3     3     3     4     4    
#3 c     11    6     7     5     5     6     6   
注意:这里,我们创建了
last\u non\u na\u col
,作为
向量
,而不是数据集中的单独列,以便于索引

数据
M您创建了所有列都作为字符的数据。那是你想要的吗?不,那不是。但我不认为这会影响结果,对吗?不会,但我很好奇你是否知道原因我知道原因,但我还没有找到解决办法。在for循环中,它经过每个i,然后是每个j,因此如果M[2,5]的值改变,它将不会再次改变值M[2,3],因为循环已经通过了M[2,3]。但是我想要的是在M[2,5]改变之后,M[2,3]改变之后。我可能需要尝试申请…嘿,阿克伦,非常感谢你的回复。在这种情况下效果很好。但规则是,如果是.na(M[i,j]),使用M[i,j+1]中的值,否则使用M[i,j-1]。但是在你的代码中,我认为它只说在缺少的单元格后面使用值。我刚刚更新了原始数据并更新了for循环。它现在运行良好。但如果你能告诉我如何在tidyverse中获得结果,那就太好了。非常感谢。@Cathy你看过postHi Akrun中更新的
for
循环代码了吗?我更新了for循环,它给了我现在想要的东西。但你能告诉我如何在tidyverse中实现这一点吗?非常感谢。请注意,我更新了原始数据,使其更加通用。谢谢,@Cathy这将是tidyverse方法的一个问题,因为它会在检查下一个循环更新之前一次更新\
 V1    V2    V3    V4    V5    V6    V7    V8    last_non_na_col
 <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>           <int>
1 a     9     8     8     NA    NA    NA    NA                  3
2 b     3     3     3     3     3     4     4                   8
3 c     11    6     7     7     7     6     6                   8
library(tidyverse)
gather(M, key, val, -V1) %>%
     group_by(V1) %>%
     fill(val, .direction = 'up') %>% 
     mutate(val = replace(val, which(is.na(val))[1], 
                         val[tail(which(!is.na(val)), 1)])) %>% 
    spread(key, val)
# A tibble: 3 x 8
# Groups:   V1 [3]
#  V1    V2    V3    V4    V5    V6    V7    V8   
#  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 a     9     8     8     NA    NA    NA    NA   
#2 b     3     3     3     3     3     4     4    
#3 c     11    6     7     5     5     6     6   
library(zoo)
last_non_na_col <- c(3, 8, 8)

for (i in seq_len(nrow(M))) {
   M[i, -1] <- na.locf(unlist(M[i, -1]), fromLast = TRUE, na.rm = FALSE)
   for (j in 3:(pmin(ncol(M), last_non_na_col[i]+1))) {      
     if (is.na(M[i,j])) { 
       M[i,j] = ifelse(!is.na(M[i,j+1]), M[i,j+1], M[i,j-1])
     }
   }   
 } 
 
M
# A tibble: 3 x 8
# Groups:   V1 [3]
#  V1    V2    V3    V4    V5    V6    V7    V8   
#  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#1 a     9     8     8     NA    NA    NA    NA   
#2 b     3     3     3     3     3     4     4    
#3 c     11    6     7     5     5     6     6    
M <- structure(list(V1 = c("a", "b", "c"), V2 = c("9", NA, "11"), 
    V3 = c("8", NA, "6"), V4 = c(NA, NA, "7"), V5 = c(NA_character_, 
    NA_character_, NA_character_), V6 = c(NA, "3", "5"), V7 = c(NA_character_, 
    NA_character_, NA_character_), V8 = c(NA, "4", "6")), .Names = c("V1", 
"V2", "V3", "V4", "V5", "V6", "V7", "V8"), row.names = c(NA, 
-3L), class = c("grouped_df", "tbl_df", "tbl", "data.frame"),
  vars = "V1", drop = TRUE, indices = list(
    0L, 1L, 2L), group_sizes = c(1L, 1L, 1L), biggest_group_size = 1L, 
  labels = structure(list(
    V1 = c("a", "b", "c")), row.names = c(NA, -3L),
  class = "data.frame", vars = "V1", drop = TRUE, .Names = "V1"))