【问题标题】:R - work on data frame rows based on conditionR - 根据条件处理数据框行
【发布时间】:2016-03-07 10:43:01
【问题描述】:

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

> 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 之前或之后显示它吗?如果它在我可以写一个简单的代码之前!

标签: r conditional


【解决方案1】:

一些可能性:

# 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 &gt; 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, ] &lt;- 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 的每一列。

【讨论】:

  • 好的,所以答案不是那么简单(至少对我来说......)。你能详细说明每个功能吗?
  • @PedroA 为简单起见,我建议idx = d$x == 0 | d$y ==0; d[idx, ] = d[idx, ] + 1。它类似于选项1,但是,我觉得它更干净一些。 IMO,我只会考虑选项 1。选项 2 和 3 虽然很聪明,但对于较大的矩阵,可能会比选项 1 慢。一般来说,最好尽可能使用子设置而不是迭代来解决 R 问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-23
  • 2022-10-14
  • 1970-01-01
  • 2020-05-17
  • 2021-04-13
相关资源
最近更新 更多