R - 根据条件

时间:2015-12-03 00:03:06

标签: r conditional

我试图了解如何根据条件处理数据帧的行。 拥有像这样的数据框

> d<-data.frame(x=c(0,1,2,3), y=c(1,1,1,0))
> d
  x y
1 0 1
2 1 1
3 2 1
4 3 0

如何为包含零值的所有行添加+1? (请注意,可以在任何列中找到零),因此结果如下所示:

  x y
1 1 2
2 1 1
3 2 1
4 4 1

以下代码似乎可以完成部分工作,但只是打印执行操作的行,拍摄的次数(2)......

> for(i in 1:nrow(d)){
+     d[d[i,]==0,]<-d[i,]+1
+ }
> d
  x y
1 1 2
2 4 1
3 1 2
4 4 1

我确定有一个简单的解决方案,也许是一个应用功能?,但我没有到达那里。

感谢。

1 个答案:

答案 0 :(得分:2)

一些可能性:

# 1
idx <- which(d == 0, arr.ind = TRUE)[, 1]
d[idx, ] <- d[idx, ] + 1
# 2
t(apply(d, 1, function(x) x + any(x == 0)))
# 3
d + apply(d == 0, 1, max)

which对矢量的使用,例如which(1:3 > 2)非常常见,而对矩阵使用较少:通过指定arr.ind = TRUE我们得到的是数组索引,即每个0的坐标:

which(d == 0, arr.ind = TRUE)
     row col
[1,]   1   1
[2,]   4   2

由于我们只对出现零的行感兴趣,因此我采用which(d == 0, arr.ind = TRUE)的第一列,并按d[idx, ] <- d[idx, ] + 1为这些行中的所有元素添加1。

关于第二种方法,apply(d, 1, function(x) x)只是逐行进行并返回同一行而不做任何修改。在any(x == 0)之后,我们会检查特定行中是否有零,并获得TRUEFALSE。但是,通过撰写x + any(x == 0),我们会根据需要将TRUEFALSE分别转换为1或0。

现在是第三种方法。 d == 0是一个逻辑矩阵,我们使用apply来查看其行。然后,当将max应用于特定行时,我们再次将TRUEFALSE转换为1,0并找到最大元素。当且仅当该行中有任何零时,此元素为1。因此,apply(d == 0, 1, max)返回0和1的向量。最后一点是,当我们写A + b时,A是一个矩阵而b是一个向量,加法是逐列的。通过这种方式,通过撰写d + apply(d == 0, 1, max),我们会根据需要将apply(d == 0, 1, max)添加到d的每一列。