删除包含零的行

时间:2013-06-28 12:38:07

标签: r dataframe subset

我有一个变量数据集

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

老年人不为零。

4 个答案:

答案 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