Prradep
Prradep

Reputation: 5716

Reason behind the transformation of a single columned dataframe to a vector after subsetting

I have a single columned data frame structure. Based on a condition, I am subsetting the data frame during run time. I have observed that the data frame is being converted into a vector after subsetting. I have achieved the data frame structure back using the as.data.frame() function.

# random generation of the values    
df <- data.frame(a=sample(1:1000,100))
#checking the class of the object
class(df)
#dimensions
dim(df)
#[1] 100   1
#subsetting the data with a random value present in the df, here 547
df_sub <- df[-df$a==547,]
# checking the subset dataset class
class(df_sub)
#[1] "integer"

I would like to know how to preserve the data frame structure without explicitly using the as.data.frame() function.

Upvotes: 1

Views: 83

Answers (3)

lmo
lmo

Reputation: 38510

R often tries to simplify objects after subsetting. If this is not desired, you can use the drop=FALSE argument to prevent such simplifications:

df_sub <- df[-df$a==547,, drop=FALSE]

> class(df_sub)
[1] "data.frame"

The drop=FALSE is also available for matrices:

myMat <- matrix(1:10, 5)

> class(myMat[, 1])
[1] "integer"
> 
> class(myMat[, 1, drop=FALSE])
[1] "matrix"
> 
> class(myMat[1, ])
[1] "integer"
> 
> class(myMat[1, , drop=FALSE])
[1] "matrix"

Upvotes: 6

J_F
J_F

Reputation: 10372

When you use the following example, the class of the subset is still a data.frame:

set.seed(1)
df <- data.frame(a = sample(1:1000,100), b = sample(1:1000,100))
class(df)
#data.frame
df_sub <- df[-df$a == 706,]
class(df_sub)
#data.frame

In your case you have a 100x1 data.frame, which will automatically be interpreted as a vector. In my example, it is still a data.frame.

When you want to keep the data.frame, you had to use:

df_sub <- subset(df, a != 706)

Regards,

J_F

Upvotes: 2

Qaswed
Qaswed

Reputation: 3879

You can use subset:

df_sub <- subset(df, a != 547)
class(df_sub) #data.frame

Upvotes: 2

Related Questions