比较R中多个数据帧的内容

时间:2018-05-28 19:23:02

标签: r

在这个场景中我有多个数据帧(~100,数字可能会有所不同),但都有相同的大小。它们基本上都是指标,我需要将它们全部交叉。请参阅以下代码:

df1 <- data.frame(col1=c("a","b","c","d"),col2=c(NA,NA,NA,NA),col3=c(NA,"X",NA,"X"),col4=c("X",NA,NA,"X"))
df2 <- data.frame(col1=c("a","b","c","d"),col2=c("X","X",NA,NA),col3=c(NA,NA,NA,"X"),col4=c(NA,NA,NA,NA))
df3 <- data.frame(col1=c("a","b","c","d"),col2=c(NA,NA,"X",NA),col3=c(NA,NA,NA,NA),col4=c(NA,"X",NA,NA))

如果此单元格中至少有一个数据框包含X,那么我需要创建的是包含X的输出数据框:

output <- data.frame(col1=c("a","b","c","d"),col2=c("X","X","X",NA),col3=c(NA,"X",NA,"X"),col4=c("X","X",NA,"X"))

我可以使用嵌套循环执行此操作,但必须有一些聪明的快速方法来实现此结果。

3 个答案:

答案 0 :(得分:0)

这样的东西?

    dfs <- list(df1, df2, df3)
    index <- lapply(dfs, function(x) apply(x[,2:4], 1, function(y) all(is.na(y))))
    output2 <- list()
    for(i in 1:length(dfs)){
      output2[[i]] <- dfs[[i]][!index[[i]],]
    }
    output <- do.call(rbind, output)

答案 1 :(得分:0)

假设我们从一个空的df开始,我们将填充其中的列:

out <- data.frame(col1=c("a","b","c","d"), col2=NA, col3=NA, col4=NA)

以下是使用所需属性构建单个列的一种方法:

out$col2 <- sapply(1:nrow(out), function(r){
  ifelse(sum(!is.na(c(df1$col2[r], df2$col2[r], df3$col2[r]))) == 0, NA, "X")
})

对列进行抽象,我们可以编写一个这样的函数:

make_output_column <- function(cname){
  sapply(1:nrow(out), function(r){
    values <- c(df1[[cname]][r], df2[[cname]][r], df3[[cname]][r])
    ifelse(sum(!is.na(values)) == 0, NA, "X")
  })
}

然后将它应用于我们想要构建的所有列,以创建所需的输出:

cols <- c("col2", "col3", "col4")
out[, cols] <- lapply(cols, make_output_column)

## col1 col2 col3 col4
##    a    X <NA>    X
##    b    X    X    X
##    c    X <NA> <NA>
##    d <NA>    X    X

答案 2 :(得分:0)

以下是do.callpmax

的技巧
# put your data.frames into a list
myList <- mget(ls(pattern="df\\d"))

有关此行的详细信息,请参阅我对this post的回答。

cbind(myList[[1]][1], do.call(function(...) pmax(..., na.rm=TRUE),
                              lapply(myList, "==", "X"))[, 2:4])
  col1 col2 col3 col4
1    a    1   NA    1
2    b    1    1    1
3    c    1   NA   NA
4    d   NA    1    1

此处,myList[[1]][1]从列表中的某个data.frames中拉出第一列,以返回带有单个列的data.frame。您可以等效地使用df[1]lapply(myList, "==", "X")遍历data.frames列表,如果X包含在数据中的单元格中,则返回值TRUE和FALSE。然后do.call使用pmax返回TRUE,FALSE和NA列表的每个单元格的最大值。

如果使用&#34; X&#34;而不是1s非常重要,那么请按照

进行操作
dat[dat == 1] <- "X"