我还有更多的概念性问题。我正在寻找一种从数据框中删除整个行的方法,如果该行包含对第二个数据框中不存在的数据的引用。下面的代码将为您提供此问题的数据集。
v1 <- c(1, 2, 3, 4, 5, 6, 8)
v2 <- 100
nodedf <- data.frame(v1, v2)
colnames(nodedf) <- ("nid", "extra_variable")
v3 <- c(1, 2)
v4 <- c(1, 5)
v5 <- c(2, 6)
v6 <- c(3, 7)
v7 <- c(4, 9)
elementdf <- data.frame(v3, v4, v5, v6, v7)
colnames(elementdf) <- c("eid", "n1", "n2", "n3", "n4")
基本上,如果引用elementdf
中不存在的节点ID(n1,n2,n3,n4),我希望删除nodedf
中的任何行。我知道这可能是一个相当简单的问题,但是我对这种事情确实不是很擅长。谢谢。
编辑:现在我正在做相反的事情,在这里我想删除nodedf的行,这些行引用了elementdf中不存在的节点。
起初,我试图像这样重新排列旧代码块:
orphannodesbye<- nodedf[apply(nodedf[,1], 1, function(x) all(x %in% elementdf[,2:5])),]
但是,我收到一条错误消息:
Error in apply(nodedf[, 1], 1, function(x) all(x %in% elementdf[, 2:5])) :
dim(X) must have a positive length
我希望输出是两个字段(或更多,因为我的实际数据集有更多)nid
和extra_variable
的整个df。
答案 0 :(得分:2)
这是基本的R解决方案
elementdf[apply(elementdf[,-1], 1, function(x) all(x %in% nodedf$nid)),]
说明:
apply
的工作方式是将一个函数(在这种情况下为自定义函数)“应用”到对象x
的每一行(函数中的变量elementdf
)。如果我们想按列进行操作,则可以将1
更改为2
。
我们正在使用的函数查看x
中的每个元素(elementdf
中的一行),并测试它是否也位于nodedf
中。 %in%
是一个特殊函数,它返回逻辑向量,x
中每个逻辑元素。如果所有元素都是all
(意味着它们都在TRUE
中,则TRUE
函数将返回nodedf
,否则返回FALSE
。
因此,最后,apply语句将返回逻辑向量,具体取决于每行是否在nodedf
中找到元素。
要获取nodedf
中不在的每一行的值,您可以
apply(elementdf[,-1], 1, function(x) x[!(x %in% nodedf$nid)])
您将注意到的已经与上面的代码行非常相似。除非在这种情况下,否则apply
语句将返回一个列表。从您给出的示例中,它将显示一个长度为2的列表,其中第一个元素为numeric(0)
,第二个元素为包含7的向量。如果一行中有多个违规者,则将显示每个。
要删除nodedf
中没有引用的行,您可以这样做
elementdf
nodedf[nodedf$nid %in% unique(unlist(elementdf[,-1])),]
部分仅捕获unique(unlist(...))
中的所有唯一值,然后将它们转换为数字向量。