【发布时间】:2015-10-14 14:57:40
【问题描述】:
我有一个大的 data.frame,有 ~100.000 行和 12 列(3 列包含变量,9 个值/测量值),其中有很多 NA,类似于这些:
##Example data.frame
Var1 <- c(rep("N01", 9), rep("N02",9))
Var2 <- c("a","a","a","b","b","b","c","c","c","a","a","a","b","b","b","c","c","c")
Val1 <- c(NA,2,1,2,NA,1, NA,2,NA, 2,NA,NA,NA,2,NA,1,NA,2)
Val2 <- c(2,NA,1,NA,2,NA,2,NA,2,NA,2,2,2,NA,2,NA,2,NA)
data <- data.frame(Var1,Var2,Val1,Val2)
data
Var1 Var2 Val1 Val2
N01 a NA 2
N01 a 2 NA
N01 a 1 1
N01 b 2 NA
N01 b NA 2
N01 b 1 NA
N01 c NA 2
N01 c 2 NA
N01 c NA 2
N02 a 2 NA
N02 a NA 2
N02 a NA 2
N02 b NA 2
N02 b 2 NA
N02 b NA 2
N02 c 1 NA
N02 c NA 2
N02 c 2 NA
Var1 和 Var2 是变量(Var1 = PlotID,Var2 = SubplotID)。
Val1 和 Val2 是 Var1 和 Var2 的每个组合的值(测量值)。
现在我想尽可能多地删除不必要的 NA,例如Val1 和 Val2 都包含一个“N01 a”的 NA,但在不同的行中。如果 data.frame 如下所示(只是手动订购),我可以轻松删除只有 NA 的行(对于 Val1 和 Val2)。
#Ordered manually
Val1 <- c(2,1,NA,2,1,NA,2,NA,NA,2,NA,NA,2,NA,NA,2,1,NA)
Val2 <- c(2,1,NA,2,NA,NA,2,2,NA,2,2,NA,2,2,NA,2,NA,NA)
data2 <- data.frame(Var1,Var2,Val1,Val2)
Var1 Var2 Val1 Val2
N01 a 2 2
N01 a 1 1
N01 a NA NA
N01 b 2 2
N01 b 1 NA
N01 b NA NA
N01 c 2 2
N01 c NA 2
N01 c NA NA
N02 a 2 2
N02 a NA 2
N02 a NA NA
N02 b 2 2
N02 b NA 2
N02 b NA NA
N02 c 2 2
N02 c 1 NA
N02 c NA NA
因此,最后我想要一个如下所示的 data.frame:
Var1 Var2 Val1.s Val2.s
1 N01 a 1 1
2 N01 a 2 2
3 N01 b 1 2
4 N01 b 2 NA
5 N01 c 2 2
6 N01 c NA 2
7 N02 a 2 2
8 N02 a NA 2
9 N02 b 2 2
10 N02 b NA 2
11 N02 c 1 2
12 N02 c 2 NA
我写了一个小循环,它只是在 Var1 和 Var2 的所有可能组合中子集 data.frame
而不是分别订购 Val1 和 Val2 并删除 Val1 和 Val2 仅为 NA 的行。
它可以工作,但它似乎相当复杂,对于大 data.frame 来说它不是很快。有没有人知道更好的方法来获取第一个 data.frame 到最后一个。
在此先感谢
#Small loop
library(dplyr)
level.var1 <- unique(Var1)
level.var2 <- unique(Var2)
Res.list1 <- list()
Res.list2 <- list()
for(i in 1:length(level.var1)){
df.1 <- dplyr::filter(data, Var1==level.var1[i])
for(o in 1:length(level.var2)){
df.2 <- dplyr::filter(df.1, Var2==level.var2[o])
Val1.s <- sort(df.2$Val1, na.last=TRUE)
Val2.s <- sort(df.2$Val2, na.last=TRUE)
df.3 <- data.frame(df.2[,c(1:2)], Val1.s, Val2.s)
row_to_del <- apply(df.3[,c(3,4)], 1, function(x) all(is.na(x)))
df.4 <- df.3[!row_to_del,]
Res.list1[[o]] <- df.4
}
df.5 <- do.call(rbind, Res.list1)
Res.list2[[i]] <- df.5
}
Res.final <- do.call(rbind, Res.list2)
【问题讨论】: