我有两个不同的数据帧,格式如下:
DF1 -
v1 v2 v3 v4 v5
a 1 2 +
b 5 2 + +
c 5 2 + +
d 4 3 + +
e 1 5 + +
f 3 5
g 4 2
h 3 1
i 5 5 + +DF2 -
v1 v2 v3 v4
a 1 2 +
b 5 2 + +
c 5 2 +
d 4 3 +
e 1 5 +
f 3 5
g 4 2
h 3 1
i 5 5 + 我的脚本给出了v1 & v2的散点图,但是首先我删除了v3-v4或v3-v5中至少有一个"+“的行。
我的数据帧可以更大,有更多的v1-v2对,但总是有v3-v4或v3-v5列"+“。我手动调整代码以指定要绘制的列以及要删除的行,这取决于我正在处理的DF格式。
它工作得很好,但我想让脚本更具有交互性,如下所示:
# Select v3-v4 or v3-v5 via interactive gui to give vector of column headers.
remove.vars.vector <- select.list(names(DF), # Select columns as vector of column header names via interactive gui.
multiple = TRUE, # Can choose multiple columns.
title = "Choose variables to remove from data set", # Title on gui.
graphics = TRUE) # Allow launch of gui.
# Return columns from DF with this vector of column headers.
remove.vars.subset <- DF[remove.vars.vector]
# Return rows that have at least one "+" in v3-v4 or v3-v5.
remove.vars.subset.+ <- subset(DF, remove.vars.subset == "+")
# Removes all rows that contain >=1 NA.
complete.data.+ <- remove.vars.subset.+[complete.cases(remove.vars.subset.+), ]
# Combine by rows "complete.data.+" with DF.
combo.list <- rbind(DF,complete.data.+)
# Remove duplicate rows from combined data frame.
complete.data <- combo.list[!duplicated(combo.list, fromLast = FALSE) & !duplicated(combo.list, fromLast = TRUE),]Problem:上面的代码没有完全删除包含v3-4或v3-5中至少一个"+“的行的数据帧。问题似乎在于以下几条:
# Return rows that have at least one "+" in v3-v4 or v3-v5.
remove.vars.subset.+ <- subset(DF, remove.vars.subset == "+")我还得到了很多行,每个单元格中只有NA,因此在下一行代码中是complete.cases。
因此,最终的数据框架仍然包含一些在v3-4或v3-5中带有"+“的行。
问题
是否有更好的方法在数据帧中使用可能包含"+“的列标题向量对行进行子集?
提前谢谢你。
编辑-09/08/2016-18:54我刚刚注意到一些关于我的数据框架我没有澄清的东西。有些行在v3-v4或v3-v5中没有"+“。这些是我最终想要保留的行,这样我就可以绘制散射图。我已经编辑了相应的数据帧。我只是在寻找答案,试着去理解它们。我对R还是很陌生的。
发布于 2016-08-09 16:33:43
假设您的数据DF是
> DF
v1 v2 v3 v4 v5
1 1 2 +
2 5 2 + +
3 5 2 + +
4 4 3 + +
5 1 5 + +我选择v3和v4。然后,remove.vars.subset,按照您的代码,是
> remove.vars.subset
v3 v4
1 +
2 + +
3 +
4 +
5 + 注意,remove.vars.subset == "+"的计算值为
> remove.vars.subset == "+"
v3 v4
[1,] TRUE FALSE
[2,] TRUE TRUE
[3,] TRUE FALSE
[4,] FALSE TRUE
[5,] TRUE FALSE然后,subset将要求R从条件计算为TRUE的数据中返回行,即:
DF[c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE, TRUE, FALSE),]
连接第一列和第二列。但是在dataframe中只有5行,而逻辑向量中有10个元素。因为DF只有5行,所以NA被追加(所以DF有10行),并相应地计算表达式。所以你看到了:
> subset(DF, remove.vars.subset == "+")
v1 v2 v3 v4 v5
1 1 2 +
2 5 2 + +
3 5 2 + +
5 1 5 + +
NA NA NA <NA> <NA> <NA>
NA.1 NA NA <NA> <NA> <NA>你可能想尝试的是
DF[!apply(remove.vars.subset, MAR=1, function(x) any(x=="+")), ]
> DF[!apply(remove.vars.subset, MAR=1, function(x) any(x=="+")), ]
[1] v1 v2 v3 v4 v5
<0 rows> (or 0-length row.names)它不返回任何行,因为所有行(给定v3和v4的选择)都至少有一个"+“行。但假设我们选择了v4和v5
> DF[!apply(remove.vars.subset, MAR=1, function(x) any(x=="+")), ]
v1 v2 v3 v4 v5
1 1 2 + 发布于 2016-08-09 16:40:46
我有一个解决方案,您没有选择列,但是所有带有"+“和NAs的行都从dataframe中删除。我不知道这是否有帮助。它基于以下问题:Better way to filter a data frame with dplyr using OR?
v1 <- c(1,2,3,4,5,NA)
v2 <- c(1,2,3,4,5,NA)
v3 <- c("","+","+","","",NA)
v4 <- c("","+","","+","",NA)
v5 <- c("","+","","","",NA)
D1 <- cbind.data.frame(v1,v2,v3,v4,v5,stringsAsFactors=F)
library(dplyr)
remove.vars.vector <- c("v3","v4","v5")
condition <- c("+",NA)
D1 %>%
filter(rowSums(sapply(D1, FUN = "%in%", condition)) == 0) -> D1_new编辑:我找到了选择列的可能性,不幸的是,我没有找到按字符向量选择列的解决方案:
D1 %>% select_(remove.vars.vector) -> D1_sub # NOT working
D1 %>% select(v3:v5) -> D1_sub # working
D1 %>% select(v3,v4,v5) -> D1_sub # working
D1 %>% select_("v3","v4","v5") -> D1_sub # working
D1 %>%
filter(rowSums(sapply(D1_sub, FUN = "%in%", condition)) == 0) -> D1_newhttps://stackoverflow.com/questions/38855391
复制相似问题