2015-12-03 75 views
2

我想了解如何根据条件来处理数据帧的行。 有这样R - 根据条件对数据帧行进行操作

> 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 

我敢肯定有这一个简单的解决方案,也许一个应用函数?但我没有到达那里。

谢谢。

+0

您是否需要单独显示已更改的行,还需要在添加1之前还是之后显示它?如果它之前我可以写一个简单的代码! –

回答

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

关于第二种方法,apply(d, 1, function(x) x)只是简单地逐行进行,并且没有任何修改就返回相同的行。通过any(x == 0)我们检查一个特定行中是否有零,并得到TRUEFALSE。但是,通过编写x + any(x == 0),我们根据需要分别将TRUEFALSE转换为1或0。

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

+0

好的,所以答案并不那么简单(至少对我来说......)。你能详细说明每个功能吗? – PedroA

+0

@PedroA,当然,我会尽快更新我的答案。 – Julius

+1

@PedroA为了简单起见,我建议'idx = d $ x == 0 | d $ y == 0; d [idx,] = d [idx,] + 1'。它与选项1类似,但是,我觉得它更清洁一些。海事组织,我只会考虑选项1.方案2和3虽然很聪明,但对于较大的矩阵可能会比方案1慢。一般来说,最好在可能的情况下使用子设置而不是迭代来处理R问题。 –