Реплицируйте значение на основе значений в другом столбце в кадре данных R - PullRequest
0 голосов
/ 10 апреля 2020

Я написал некоторый код, который перебирает файлы xlsx в папке. На определенном этапе в l oop кадр данных выглядит так, как показано ниже. Я хочу добиться того, чтобы значения столбца B реплицировались вместе со значениями столбца A. Итак: реплицируйте столбец B, пока группа в столбце A не изменит значение. Если вместе с группой в столбце A нет значения, оставьте его пустым. Это приведет ко второму фрейму данных

'A' 'B' 'C'    'D'  'E'
 1  50  'ABCD'  10  20
 1      'JNHF'
 1      'edfw'
 2  100 'b984'
 2      'abcd'
 2      'abcd'
 3      'abcd'  24
 3      'b984'
 4 25   'JNHF'
 4      'JNHF'
 4      'b984'

Результат будет следующим:

'A' 'B' 'C'    'D' 'E' 
 1  50  'ABCD' 10  20
 1  50  'JNHF' 10  20
 1  50  'edfw' 10  20
 2  100 'b984'
 2  100 'abcd'
 2  100 'abcd'
 3      'abcd' 24
 3      'b984' 24
 4  25  'JNHF'
 4  25  'JNHF'
 4  25  'b984'

Для этого я написал следующий код.

 names <- c('B','D','E')

 for(j in 1:length(names)){
  for(i in 2:nrow(df)){
    if(df[,names[j]][i] == '' & df[,names[1]][i] == df[,names[1]][i-1] ){
        df[,numbers[j]][i] <- df[,names[j]][i-1] 
     }
    }
 }  

код возвращает:

 Error in if (df[, names[j]][i] == "" & df[, names[1]][i] == df[, names[1]][i -  : 
   argument is of length zero

Как мне это исправить?

Ответы [ 3 ]

0 голосов
/ 10 апреля 2020

Решение Base R (с использованием данных, предоставленных @RonakShah - спасибо):

# Convert factors to character strings: clean_df => data.frame
clean_df <- data.frame(lapply(df, function(w){if(is.factor(w)){as.character(w)}else{w}}), 
                       stringsAsFactors = FALSE)

# Replace blank stirngs with values filled downwards grouping by A: stdout
data.frame(lapply(clean_df, function(x){
        return(ave(x, clean_df$A, FUN = function(z){
          ifelse(any(!(is.na(z))), na.omit(z)[cumsum(!is.na(z))], NA)
          }
        )
      )
    }
  )
)
0 голосов
/ 10 апреля 2020

@ Тимминатор с небольшой модификацией переменной names и for l oop, как показано ниже:

names <- c("'B'","'D'","'E'")
#
for(j in 1:length(names)){
  for(i in 2:nrow(df)){
    if(df[i,names[j]] == '' & df[i,1] == df[i-1,1]){
       df[i,names[j]] <- df[i-1,names[j]] 
    }
  }
}

Мы можем получить следующий желаемый результат

> df
   'A' 'B'    'C' 'D' 'E'
1    1  50 'ABCD'  10  20
2    1  50 'JNHF'  10  20
3    1  50 'edfw'  10  20
4    2 100 'b984'        
5    2 100 'abcd'        
6    2 100 'abcd'        
7    3     'abcd'  24    
8    3     'b984'  24    
9    4  25 'JNHF'        
10   4  25 'JNHF'        
11   4  25 'b984' 

Использование следующих данных в качестве ввода

df<- structure(list("'A'" = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L, 4L,4L), 
                    "'B'" = c("50", "", "", "100", "", "", "", "", "25", "", ""), 
                    "'C'" = structure(c(2L, 7L, 6L, 1L, 4L, 4L, 4L, 5L, 3L, 7L, 5L
                    ), .Label = c("'b984'", "'ABCD'", "'JNHF'", "'abcd'", 
                                  "'b984'", "'edfw'", "'JNHF'"), class = "factor"), 
                    "'D'" = c("10", "", "", "", "", "", "24", "", "", "", ""), 
                    "'E'" = c("20","", "", "", "", "", "", "", "", "", "")), row.names = c(NA,-11L), class = "data.frame")
0 голосов
/ 10 апреля 2020

Замените пробел на NA, а затем используйте tidyr::fill.

library(dplyr)

df %>% mutate_at(vars(names), na_if, "") %>% group_by(A) %>% tidyr::fill(names)

#       A B     C    
#   <int> <chr> <fct>
# 1     1 50    ABCD 
# 2     1 50    JNHF 
# 3     1 50    edfw 
# 4     2 100   b984 
# 5     2 100   abcd 
# 6     2 100   abcd 
# 7     3 NA    abcd 
# 8     3 NA    b984 
# 9     4 25    JNHF 
#10     4 25    JNHF 
#11     4 25    b984 

data

df <- structure(list(A = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 4L, 4L, 
4L), B = c("50", "", "", "100", "", "", "", "", "25", "", ""), 
C = structure(c(2L, 5L, 4L, 3L, 1L, 1L, 1L, 3L, 5L, 5L, 3L
), .Label = c("abcd", "ABCD", "b984", "edfw", "JNHF"), 
class = "factor")), row.names = c(NA, -11L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...