我有两个数据框,其中第一个df的行名与第二个df的列名的顺序相同。例如
DF1
rows something
n1 34
n2 62
n3 15
n4 29
n5 93
DF2
rows n1 n2 n3 n4 n5
r34 2 4 0 0 1
r43 0 5 8 0 2
r75 7 2 5 0 0
我有这行代码:
df1 = df1[-which(colSums(df2) == 0),]
摆脱了df1中的第四行..
但是我遇到了没有colSums(df2)==0
的问题,在这种情况下返回integer(0)
并且代码不起作用
此外,代码行还依赖于df1
的行名和df2
的列名的顺序相同的事实......这不是最好的假设。
什么是解决问题的更好方法,哪个更强大?我认为我需要在某处使用%in%
......
答案 0 :(得分:2)
您可以尝试(假设rows
是数据集的rownames
)
df1[colSums(df2)!=0,,drop=FALSE]
# something
#n1 34
#n2 62
#n3 15
#n5 93
假设,如果colSums不为0,则获取所有行
df2$n4[1] <- 3
df1[colSums(df2)!=0,,drop=FALSE]
# something
#n1 34
#n2 62
#n3 15
#n4 29
#n5 93
df1 <- structure(list(something = c(34L, 62L, 15L, 29L, 93L)),
.Names = "something", class = "data.frame", row.names = c("n1",
"n2", "n3", "n4", "n5"))
df2 <- structure(list(n1 = c(2L, 0L, 7L), n2 = c(4L, 5L, 2L),
n3 = c(0L, 8L, 5L), n4 = c(0L, 0L, 0L), n5 = c(1L, 2L, 0L)),
.Names = c("n1", "n2", "n3", "n4", "n5"), class = "data.frame",
row.names = c("r34", "r43", "r75"))
答案 1 :(得分:1)
akrun的答案的这种变化将允许在df1和df2之间具有不同的cols /行顺序:
result <- df1[colnames(df2[which(colSums(df2)>0)]),,drop=FALSE]
result
# something
# n1 34
# n2 62
# n3 15
# n5 93
答案 2 :(得分:1)
有几种更安全的替代方案。首先,不要使用-which()结构,原因正如你所说明的那样:不匹配的情况下返回一个空的向量,而没有任何东西的负数仍然是空的。考虑在which()参数中使用逻辑否定。请注意,您实际上并不匹配行名称,因为which
返回一个数字向量:
df1 = df1[ which(colSums(df2) != 0),] # numerical indexing, not character
#now a vector
或者使用与rownames不匹配的逻辑索引:
df1 = df1[ colSums(df2) != 0,] # Logical indexing
# now a vector
还可以将其用于也保留数据帧结构的子集:
> subset(df1, !colSums(df2) == 0)
something
n1 34
n2 62
n3 15
n5 93
如果你想使用&#34;]&#34;来保持数据帧结构?然后添加drop = FALSE作为第三个参数:
df1[ colSums(df2) != 0, , drop=FALSE]
something
n1 34
n2 62
n3 15
n5 93