Есть ли способ упростить приведенный ниже код с помощью векторов?

Я использую R. Мне нужно создать новый столбец во фрейме данных, который представляет собой сумму трех переменных. Сумма должна иметь место только в том случае, если для каждой из трех переменных есть числовые значения. Другими словами, если есть какие-либо NA или пробелы, сумма не должна иметь место.

Я написал код ниже, который работает, но хотел бы его упростить. Я заинтересован в использовании векторов, чтобы избежать повторения в моем коде.


data.x <- data.frame('time' = c(1:11),
                   'x' = c(5,3,"",'ND',2,'ND',7,8,'ND',1," "))
data.x[data.x == ''] <- 'NA'
data.x[data.x == ' '] <- 'NA'
data.x[data.x == 'ND'] <- 'NA'
data.x.na.omit <- na.omit(data.x)             

data.y <- data.frame('time' = c(1:8),
                     'y' = c(5,2,3,1,2,NA,NA,8))
data.y[data.y == ''] <- 'NA'
data.y[data.y == ' '] <- 'NA'
data.y[data.y == 'ND'] <- 'NA'
data.y.na.omit <- na.omit(data.y)  


data.z <- data.frame('time' = c(1:5),
                     'z' = c(1:5))
data.z[data.z == ''] <- 'NA'
data.z[data.z == ' '] <- 'NA'
data.z[data.z == 'ND'] <- 'NA'
data.z.na.omit <- na.omit(data.z)   

data.x.y <- merge.data.frame(data.x.na.omit, data.y.na.omit, by.x = "time", by.y = "time")
data.x.y.z <- merge.data.frame(data.x.y, data.z.na.omit, by.x = "time", by.y = "time" )

data.x.y.z$x <- as.numeric(data.x.y.z$x)
data.x.y.z$y <- as.numeric(data.x.y.z$y)
data.x.y.z$z <- as.numeric(data.x.y.z$z)

data.x.y.z$result <- data.x.y.z$x + data.x.y.z$y + data.x.y.z$z


person user11036517    schedule 13.04.2019    source источник


Ответы (1)


Я не вижу особенно хороших способов использования векторов, чтобы избежать повторения. Однако я бы предложил следующее:

  1. Удаление NA строк путем однократной оценки столбца result, поэтому вам не нужно делать это для каждого из x, y и z.
  2. Установка stringsAsFactors на FALSE, чтобы использование одной строки, такой как data.x$x <- as.numeric(data.x$x), автоматически приводило строки к NA, и вам не нужно делать это отдельно.
  3. Ввод данных в виде единого кадра данных (путем добавления NA в конец столбцов y и z), а не создание data.x, data.y и data.z с последующим слиянием.

Например, код с этими предложениями может выглядеть так:

# Create merged data
data <- data.frame('time' = c(1:11),
                   'x' = c(5,3,"",'ND',2,'ND',7,8,'ND',1," "),
                   'y' = c(5,2,3,1,2,NA,NA,8, rep(NA, 3)),
                   'z' = c(1:5, rep(NA, 6)),
                   stringsAsFactors=F)

# Convert x, y and z to numeric
for(col in c("x", "y", "z"))
  class(data[,col]) <- "numeric"

# Add x, y and z together
data$result <- data$x + data$y + data$z

# Remove NAs at the end
data <- na.omit(data)

Если ваши источники данных таковы, что вы не можете вводить их как единый фрейм данных, но вам нужно их объединить, вы можете заменить раздел «Создать объединенные данные» на что-то вроде этого:

# Create separate data
data.x <- data.frame('time' = c(1:11),
                     'x' = c(5,3,"",'ND',2,'ND',7,8,'ND',1," "),
                     stringsAsFactors=F)
data.y <- data.frame('time' = c(1:8),
                     'y' = c(5,2,3,1,2,NA,NA,8),
                     stringsAsFactors=F)
data.z <- data.frame('time' = c(1:5),
                     'z' = c(1:5),
                     stringsAsFactors=F)

# Merge data
data.xy <- merge(data.x, data.y)
data <- merge(data.xy, data.z)

# Now continue main code suggestion from the 'Convert x, y and z to numeric' section
person hodgenovice    schedule 13.04.2019
comment
Спасибо за помощь! - person user11036517; 13.04.2019
comment
@ user11036517 Не за что. Если ответ решает вашу проблему, рекомендуется принять его, нажав на галочку. Это поможет другим увидеть, что проблема решена. В качестве альтернативы вы можете проголосовать, если это просто полезно. Подробнее об этом можно прочитать здесь. Конечно, вы не обязаны это делать и не должны, если ответ бесполезен. - person hodgenovice; 03.06.2019