R - 如何按条件和列操作数据

时间:2015-08-23 08:45:25

标签: r

看起来这应该是一个简单的应用任务,但我仍然无法弄明白。我有这样的数据:

x1= c(1,1,2,3,1,2,4) 
x2= c(1,2,2,6,2,3,1) 
x3= c(1,1,1,0,0,0,0) 
x4= c(1,0,0,0,0,3,1) 

df=data.frame( x1,x2,x3,x4) 
df
  x1 x2 x3 x4
1  1  1  1  1
2  1  2  1  0
3  2  2  1  0
4  3  6  0  0
5  1  2  0  0
6  2  3  0  3
7  4  1  0  1 

这样的矢量:

m= c(1,1,0,0)
rbind(df,m)
df=rbind(df,m)
df
  x1 x2 x3 x4
1  1  1  1  1
2  1  2  1  0
3  2  2  1  0
4  3  6  0  0
5  1  2  0  0
6  2  3  0  3
7  4  1  0  1
8  1  1  0  0

现在我希望列中的所有值等于同一列中最后一行(m向量)上的值更改为0,其他值更改为1.例如df [ 1,2]是1,它与m [2]相同,因此df2 [1,2]的值为0.新数据集将如下所示:

df2
  x1 x2 x3 x4
1  0  0  1  1
2  0  1  1  0
3  1  1  1  0
4  1  1  0  0
5  0  1  0  0
6  1  1  0  1
7  1  0  0  1
8  1  1  0  0

2 个答案:

答案 0 :(得分:3)

使用' df'在rbind之后的数据集,我们在除了最后一行(df[-8,])之外的所有行和最后一行进行比较,以便长度相同。 (df[8,][col(df[-8,])])。这将返回一个逻辑矩阵,可以通过用+换行将其强制转换为二进制。然后我们用最后一行' df'来对二进制输出进行rbind。 (df[8,])获得预期的输出。

df2 <- rbind(+(df[-8,]!=df[8,][col(df[-8,])]), df[8,])
df2
#  x1 x2 x3 x4
#1  0  0  1  1
#2  0  1  1  0
#3  1  1  1  0
#4  1  1  0  0
#5  0  1  0  0
#6  1  1  0  1
#7  1  0  0  1
#8  1  1  0  0

或者正如@DavidArenburg提到的那样,通过比较“df&#39;在使用rbind(&#39; m&#39;)的vector步骤之前。

m1 <-  rbind(+(df != m[col(df)]), m)
row.names(m1) <- NULL

为了更好地理解它,我们复制了&#39; m&#39;使用col函数的向量,该函数返回&#39; df&#39;

的数字列索引
 col(df)
 #     [,1] [,2] [,3] [,4]
 #[1,]    1    2    3    4
 #[2,]    1    2    3    4
 #[3,]    1    2    3    4
 #[4,]    1    2    3    4
 #[5,]    1    2    3    4
 #[6,]    1    2    3    4
 #[7,]    1    2    3    4
使用

 m[col(df)]
 #[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

&#39; m&#39;中的第一个元素即1次复制7次,第二次1次复制7次,依此类推......

现在,长度是相同的

 length( m[col(df)])
 #[1] 28
 prod(dim(df))
 #[1] 28

进行逐元素比较。

 df != m[col(df)]
 #      x1    x2    x3    x4
 #[1,] FALSE FALSE  TRUE  TRUE
 #[2,] FALSE  TRUE  TRUE FALSE
 #[3,]  TRUE  TRUE  TRUE FALSE
 #[4,]  TRUE  TRUE FALSE FALSE
 #[5,] FALSE  TRUE FALSE FALSE
 #[6,]  TRUE  TRUE FALSE  TRUE
 #[7,]  TRUE FALSE FALSE  TRUE

在最后一步中,我们将此强制转换为二进制并将其绑定到&#39; m&#39;。

另一种选择是将sweepMARGIN=2

一起使用
rbind(+(sweep(df, 2 ,m ,'!=')), m)

答案 1 :(得分:2)

您可以尝试以下方法:

df2 <- t(t(df) != m) * 1 # create a logical dataframe that compares rows with m 
    # and transpose result back to original format,
    # coerce TRUE and FALSE entries into numerical values by multiplying with 1
df2[nrow(df2),] <- m #keep the last row unchanged
#> df2
#  x1 x2 x3 x4
#1  0  0  1  1
#2  0  1  1  0
#3  1  1  1  0
#4  1  1  0  0
#5  0  1  0  0
#6  1  1  0  1
#7  1  0  0  1
#8  1  1  0  0