我有一个变量数据集
Year Age Bag Computer
2008 0 4 4
2008 1 5 3
2008 2 5 12.5
2008 3 5 15
2008 4 5 33
2008 5 5 11
2008 85 5 3.5
2008 . . .
2008 108 0 0
2008 109 0 0
2008 110+ 0 0
我需要在R中对此进行子集化,以便删除数据库中的所有零并获得此最终表格
Year Age Bag Computer
2008 0 4 4
2008 1 5 3
2008 2 5 12.5
2008 3 5 15
2008 4 5 33
2008 5 5 11
2008 7 5 14.5
2008 8 5 17
老年人不为零。
答案 0 :(得分:2)
如果要识别包含在行或计算机列中的0行(假设您的数据框名为dat
,则可以使用:
bad.rows <- which(dat$Bag==0 | dat$Computer==0)
您可以将它们分组为:
subset(dat, !rownames(dat) %in% bad.rows)
或者您可以跳过识别行的步骤,只使用子集:
subset(dat, Bag!=0 & Computer!=0)
请注意,否定均等意味着可能需要切换到使用“&amp;” (或许这不是你想要的。)你的描述在这方面有点模糊。如果两者都为零,或者删除年龄超过特定年龄的年龄,您可能只想删除它们。
subset(dat, !(Bag==0 & Computer==0) ) # ages with any non-zero
答案 1 :(得分:1)
要对表格进行子集化,请使用......好,subset
:
newTable <- subset(oldTable, Bag != 0)
或者,相当于
newTable <- oldTable[oldTable$Bag != 0, ]
目前还不清楚你的标准究竟是什么。如果您要删除Bar
或 Computer
为0的任何行,则可以合并条件:
newTable <- subset(oldTable, Bag != 0 & Computer != 0)
(另一种语法也有效。)
答案 2 :(得分:1)
看起来您想要进行子集化,如果除any
之外的Age
列中有零,则删除该行。我使用apply
来遍历行并使用逻辑比较来查看any
值(年龄除外)是否等于0
所以我这样做(假设数据库是叫df
):
# Return a logical vector. TRUE if any value in row == 0
# x[-2] removes the df$Age column from comparison
idx <- apply( df , 1 , function(x) any( x[-2] == 0 ) )
# Use this to subset
df[ !idx , ]
# Year Age Bag Computer
#1 2008 0 4 4.0
#2 2008 1 5 3.0
#3 2008 2 5 12.5
#4 2008 3 5 15.0
#5 2008 4 5 33.0
#6 2008 5 5 11.0
#7 2008 85 5 3.5
因为@Arun抱怨我的速度很慢(我当时 - 但是我想方便代码,这很容易让你坚持使用大量的数据帧或矩阵来测试)我投入了规范(和最快的!)子集化的方式是:
df[ df$Bag == 0 | df$Computer == 0 , ]
无论如何,@Konrad给出的答案中隐含着这一点。
答案 3 :(得分:1)
另一种方式:
df[with(df, complete.cases(cbind(Bag, Computer)/0)), ]
对更大数据进行基准测试:
set.seed(45)
sz <- 1e6
df <- data.frame(Year=sample(1930:2013, sz, replace=TRUE),
Age=sample(100, sz, replace=TRUE),
Bag = sample(0:5, sz, TRUE),
Computer=sample(0:10, sz, TRUE))
simon <- function(dt) {
idx <- apply( dt , 1 , function(x) any( x[-2] == 0 ) )
dt[ !idx , ]
}
dwin_konrad <- function(dt) {
subset(dt, Bag != 0 & Computer != 0)
}
arun <- function(dt) {
dt[with(dt, complete.cases(cbind(Bag, Computer)/0)), ]
}
require(microbenchmark)
microbenchmark(o1 <- simon(df), o2 <- dwin_konrad(df), o3 <- arun(df), times=5)
Unit: milliseconds
expr min lq median uq max neval
o1 <- simon(df) 15971.7720 16348.4055 16540.6794 18153.9090 18443.5480 5
o2 <- dwin_konrad(df) 402.7010 419.3139 494.9592 723.1468 745.5400 5
o3 <- arun(df) 320.8689 324.0388 334.0515 335.8886 366.6647 5
identical(o1, o2) # TRUE
identical(o1, o3) # TRUE