用其他列的信息替换0 [dplyr]

时间:2018-10-03 17:28:29

标签: r dplyr

example.df <- data.frame(GLX = sample(300:600, 200, replace = T), GLY = sample(300:600, 200, replace = T), 
                         GRX = sample(300:600, 200, replace = T), GRY = sample(300:600, 200, replace = T))
    example.df$GLX[1:20] <- 0
    example.df$GLY[1:20] <- 0
    example.df$GRX[70:100] <- 0
    example.df$GRY[70:100] <- 0
    example.df[150:170, ] <- 0

我有一个data.frame,其中包含左眼(GL)和右眼(GR)的眼睛坐标(X&Y)。

在GLX和GLY均为0的情况下,我希望将0分别替换为GRX和GRY。我也希望这能以相反的方式发生。

如果所有4列均为0,则我不希望采取任何其他措施。我已经做过一个for循环,但这非常慢。使用dplyr有什么办法吗?我无法正常工作。

非常感谢!

3 个答案:

答案 0 :(得分:2)

我只是直接在基地进行替换:

l_0 = example.df$GLX == 0 & example.df$GLY == 0
r_0 = example.df$GRX == 0 & example.df$GRY == 0

example.df[l_0 & ! r_0, c("GLX", "GLY")] = example.df[l_0 & ! r_0, c("GRX", "GRY")]
example.df[r_0 & ! l_0, c("GRX", "GRY")] = example.df[r_0 & ! l_0, c("GLX", "GLY")]

据我所知,dplyr没有一种便捷的方法可以针对单个条件立即替换多列,这使得在base中执行操作更加方便。尽管dplyr通常可以节省输入并使内容比基本内容更具可读性,但是我发现以上内容非常可读,并且dplyr的替代方式由于重复进行细微更改而令人讨厌且冗长且不可读/容易产生错字。 >

example.df %>% mutate(
  GLX = if_else(GLX==0 & GLY==0, GRX, GLX),
  GLY = if_else(GLX==0 & GLY==0, GRY, GLY),
  GRX = if_else(GRX==0 & GRY==0, GLX, GRX),
  GRY = if_else(GRX==0 & GRY==0, GLY, GRY)
)
  

如果所有4列均为0,则我不想采取任何进一步的措施。

我编写了与您在问题中描述的内容相匹配的代码,但是如果我们忽略“如果所有4列都为0”位,则可以简化一点-如果所有4列都为0,则用每列替换0其他没有任何伤害。这样就可以简单地将条件设为l_0r_0,而不是l_0 & ! r_0r_0 & ! l_0

答案 1 :(得分:1)

您可以使用以下表单,在其他列的mutate中添加其他if_elses:

example.df %>% mutate(GLX = if_else(GLX==0 & GLY==0,GRX,GLX))

if_else计算第一个位置的表达式,如果为true,则返回第二个值;如果为false,则返回最后一个值

答案 2 :(得分:1)

另一种方式:

library(data.table)
setDT(example.df)

lcols = c("GLX", "GLY"); rcols = c("GRX", "GRY")
example.df[.(0,0), on=lcols, (lcols) := .SD, .SDcols=rcols]
example.df[.(0,0), on=rcols, (rcols) := .SD, .SDcols=lcols]

这是使用“对”每对列的联接来查找应进行替换的行。

正如Gregor所建议的,我忽略了多余的条件“如果所有4列都为0,则我不想采取任何进一步的措施。”