Есть ли способ, которым я могу упростить приведенный ниже код, используя векторы? - PullRequest
0 голосов
/ 13 апреля 2019

Я использую 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

1 Ответ

0 голосов
/ 13 апреля 2019

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

  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
...