Transform duplicate values to 0 by keeping an element in the conditional R

Asked

Viewed 94 times

3

Suppose there is a database in which:

x    y     z
a  2015  122.4
a  2015  122.4
b  2016  200.5
a  2014  300.6
c  2016  80.1

What I was wondering is with making a programming in R that transforms the repeated values of z of each x and y group into 0, maintaining a value of z, the final result being as:

x    y     z
a  2015  122.4
a  2015    0
b  2016  200.5
a  2014  300.6
c  2016  80.1

How to do this?

2 answers

4

Follow code, using the package dplyr. In that case, I take into account the grouping of x and y

library(dplyr)
dados <-
  structure(list(
    x = structure(c(1L, 1L, 2L, 1L, 3L), 
                  .Label = c("a", "b", "c"), class = "factor"), 
    y = c(2015L, 2015L, 2016L, 2014L, 2016L), 
    z = c(122.4, 122.4, 200.5, 300.6, 80.1)), 
    .Names = c("x", "y", "z"), row.names = c(NA, -5L), class = "data.frame")

dados %>% 
  group_by(x, y) %>% 
  transmute(z = ifelse(duplicated(z), 0, z))

3


See the function duplicated.

dados$z[duplicated(dados$z)] <- 0
dados
  x    y     z
1 a 2015 122.4
2 a 2015   0.0
3 b 2016 200.5
4 a 2014 300.6
5 c 2016  80.1

If you want to keep the original database, make a copy in advance and modify the copy, dados2 <- dados, followed by the above code (with dados2).

Dice:

dados <-
structure(list(x = structure(c(1L, 1L, 2L, 1L, 3L), .Label = c("a", 
"b", "c"), class = "factor"), y = c(2015L, 2015L, 2016L, 2014L, 
2016L), z = c(122.4, 0, 200.5, 300.6, 80.1)), .Names = c("x", 
"y", "z"), row.names = c(NA, -5L), class = "data.frame")

EDITION.

After seeing Rafael Cunha’s answer I noticed that a fundamental point of the question had failed, that the repeated or duplicated values should be grouped by the columns x and y. The following reply gives account of this request of the PO.

dados$z <- ave(dados$z, dados$x, dados$y, FUN = function(.z)
                ifelse(duplicated(.z), 0, .z))

Browser other questions tagged

You are not signed in. Login or sign up in order to post.