在这个场景中我有多个数据帧(~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"))
我可以使用嵌套循环执行此操作,但必须有一些聪明的快速方法来实现此结果。
答案 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.call
和pmax
# 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"