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

Is there a way I can simplify the code below using vectors?

我正在使用 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. 通过计算 result 列一次来删除 NA 行,因此您不必为每个 xy 和 [=16] 执行此操作=].
  2. stringsAsFactors 设置为 FALSE,这样使用像 data.x$x <- as.numeric(data.x$x) 这样的单行将自动将字符串强制转换为 NA,您不必单独执行。
  3. 将数据作为单个数据框引入(通过将 NA 添加到列 yz 的底部),而不是创建 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 merged 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