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有什么办法吗?我无法正常工作。
非常感谢!
答案 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_0
和r_0
,而不是l_0 & ! r_0
和r_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,则我不想采取任何进一步的措施。”