-2

My data is like this:

X1e  X2e  X3e  X4e
360    0    0    0
360    0    0    0
260    0    0    0
0      0    0    0
0      0    0    0
0      0    0    0
90     0    0    0
360    0  360    0
360    0  360  260

I want to remove the X1e X4e columns between 0 and 270, did not remove 0 row

for (i in c(1,4)){
  e <- assign(paste("X",i, "e",sep = ""),i)
  dat <- dat[with(dat, !((e>0)&(e<270))), ] 
}

This removes all my dat and my dat became empty. Where is my problem?

Durdu
  • 4,649
  • 2
  • 27
  • 47
maryadi
  • 103
  • 6
  • I only want to remove the row ( 260 0 0 0) ,(90 0 0 0) and row (360 0 360 260) , but it remove all the line ,I think my code is right Is there a problem with my R enviroment , but I reinstall my R from 3.5.1 to 3.4.4 the problem still remain – maryadi Oct 23 '18 at 06:24
  • 2
    *"Where is my problem?"* You're not using `assign` correctly, and in fact, you should avoid using `assign` altogether! See [Why is using assign bad](https://stackoverflow.com/questions/17559390/why-is-using-assign-bad). – Maurits Evers Oct 23 '18 at 06:38
  • Your code is definitiely not right. In your loop the variable `e` is `1` in the first iteration. Therefore all the rows get deletetd, because `1>0 & 1<270` is always true. – symbolrush Oct 23 '18 at 06:44

4 Answers4

2

Base R Solution:

dat[!(dat$X1e>0 & dat$X1e<270) & !(dat$X4e>0 & dat$X4e<270),]

OR

Using sqldf:

library(sqldf)
sqldf("select * from dat where X1e not between 1 AND 270 AND X4e not between 1 AND 270")

Output:

   X1e X2e X3e X4e
1 360   0   0   0
2 360   0   0   0
3   0   0   0   0
4   0   0   0   0
5   0   0   0   0
6 360   0 360   0
Saurabh Chauhan
  • 3,161
  • 2
  • 19
  • 46
2

Create the column names of interest

cidx <- paste0("X", c(1, 4), "e")

Perform the logical operations on each column

test <- !(df[,cidx] > 0 & df[,cidx] < 270)

Sum (logical 'and') across rows to find those where all columns are TRUE

ridx <- rowSums(test) == length(cidx)

Subset the original data.frame

df[ridx,]
Martin Morgan
  • 45,935
  • 7
  • 84
  • 112
1

Like this?

library(tidyverse)
 df<-read.table(text="X1e  X2e  X3e  X4e
 360    0    0    0
            360    0    0    0
            260    0    0    0
            0      0    0    0
            0      0    0    0
            0      0    0    0
            90     0    0    0
            360    0  360    0
            360    0  360  260",header=T)
 df%>%
   filter_at(vars(X1e,X4e), all_vars(.<=0 | .>270))
  X1e X2e X3e X4e
1 360   0   0   0
2 360   0   0   0
3   0   0   0   0
4   0   0   0   0
5   0   0   0   0
6 360   0 360   0
jyjek
  • 2,627
  • 11
  • 23
1

Yet another solution.
I usually don't like subset because it uses non standard evaluation and it is slow but here it goes.

subset(df, (X1e <= 0 | X1e >= 270) & (X4e <= 0 | X4e >= 270))
#  X1e X2e X3e X4e
#1 360   0   0   0
#2 360   0   0   0
#4   0   0   0   0
#5   0   0   0   0
#6   0   0   0   0
#8 360   0 360   0
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66