有没有一种方法可以使用向量简化下面的代码?

时间:2019-04-13 06:35:52

标签: r simplification

我正在使用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 :(得分:0)

我没有看到使用 vector 来避免重复的特别好的方法。我会建议以下内容:

  1. 通过一次评估NA列来删除result行,因此您不必对xyz中的每一个都执行此操作。
  2. stringsAsFactors设置为FALSE,以便使用像data.x$x <- as.numeric(data.x$x)这样的一行将自动将字符串强制转换为NA,而您不必单独进行操作。
  3. 将数据作为单个数据帧引入(通过在列NAy的底部添加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