2

我有一个变量数据集

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

4 回答 4

2

如果您想识别 0 出现在 Bag 或 Computer 列中的行(假设您的数据框名为dat,您将使用:

bad.rows <- which(dat$Bag==0 | dat$Computer==0)

您可以将它们子集为:

subset(dat, !rownames(dat) %in% bad.rows)

或者您可以跳过识别行的步骤,只使用子集:

subset(dat, Bag!=0 & Computer!=0)

请注意,对等式的否定意味着可能需要切换到使用“&”(或者这可能不是您想要的。)您在这方面的描述有点含糊。如果两者都为零,您可能只想删除它们,或者删除在特定年龄以上全为零的年龄。

subset(dat, !(Bag==0 & Computer==0) ) #  ages with any non-zero
于 2013-06-28T14:04:55.260 回答
1

要对表进行子集化,请使用……好吧,subset

newTable <- subset(oldTable, Bag != 0)

或者,等效地,

newTable <- oldTable[oldTable$Bag != 0, ]

目前尚不清楚您的标准到底是什么。如果要删除其中Bar or Computer为 0 的任何行,则可以组合条件:

newTable <- subset(oldTable, Bag != 0 & Computer != 0)

(其他语法也适用。)

于 2013-06-28T13:40:47.453 回答
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 给出的答案都隐含地涵盖了这一点。

于 2013-06-28T14:04:17.983 回答
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
于 2013-06-28T17:48:03.970 回答