1

I have a question about upgrade values in a dataframe. The dataframe looks like this:

    P1    P2   P3   P4   P5   P6
A    1    0    0    0    0    0
B    0    1    0    0    0    0
C    0    0    1    0    0    1
D    0    0    0    0    1    0
E    1    0    0    0    0    0
F    0    0    0    1    1    0

My problem is, that i want to upgrade some values by +1. Which means, that I have a variable P1_upgrade which contains the rows that need to be upgraded by +1. Can anyone help me with this problem? The final column must be like the below column:

> P1_upgrade <- "E"
> P3_upgrade <- "C"
> P5_upgrade <- c("D","D","F")


    P1    P2   P3   P4   P5   P6
A    1    0    0    0    0    0
B    0    1    0    0    0    0
C    0    0    2    0    0    1
D    0    0    0    0    3    0
E    2    0    0    0    0    0
F    0    0    0    1    2    0
Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
Lisann
  • 5,705
  • 14
  • 41
  • 50
  • If every column in the data frame is the same type (in this case always numeric), you would be better off using a matrix, as Яaffael demonstrates in his answer. – Richie Cotton Nov 21 '13 at 10:56

2 Answers2

0
> m <- matrix(rep(0,25),ncol=5)

> df <- as.data.frame(m)

> row.names(df) <- c("a","b","c","d","e")

> df

  V1 V2 V3 V4 V5
a  0  0  0  0  0
b  0  0  0  0  0
c  0  0  0  0  0
d  0  0  0  0  0
e  0  0  0  0  0

> up <- c("b","b","c")

# return value to dump b/c we're not interested in it and don't
# want have it clutter the terminal

> dump <- sapply(up, function(r) df[r,] <<- df[r,] + 1)

> df

  V1 V2 V3 V4 V5
a  0  0  0  0  0
b  2  2  2  2  2
c  1  1  1  1  1
d  0  0  0  0  0
e  0  0  0  0  0
Raffael
  • 19,547
  • 15
  • 82
  • 160
  • Beware of using `<<-` due to its potentially unintended side effects. See http://stackoverflow.com/a/5785757/496803 – thelatemail Nov 21 '13 at 11:15
0

This problem can be simplified quite a bit if you change the way you store the variables to be updated, e.g.:

dat <- structure(c(1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0), .Dim = c(6L, 6L),
.Dimnames = list(c("A", "B", "C", "D", "E", "F"), c("P1","P2", "P3", "P4", "P5", "P6")))

Record your upgrades in a data.frame. Storing related items in a single object like a list or a data.frame has several advantages, most notably avoiding the need for complex loops working on multiple items if you find you need to apply a common change to all the items.

upg <- mget(ls(pattern="_upgrade"))
names(upg) <- gsub("_upgrade","",names(upg))
upg <- data.frame(
         row=unlist(upg),
         col=rep(names(upg),sapply(upg,length)),
         count=1,
         stringsAsFactors=FALSE
        )

#    row col count
#P1    E  P1     1
#P3    C  P3     1
#P51   D  P5     1
#P52   D  P5     1
#P53   F  P5     1

aggregate the upgrades by row/column index:

upg <- aggregate( count ~ row + col , data=upg, sum)

#  row col count
#1   E  P1     1
#2   C  P3     1
#3   D  P5     2
#4   F  P5     1

Add the upgrade values (though you will need to change dat to a matrix first for this to work):

dat <- as.matrix(dat)
dat[ as.matrix(upg[1:2]) ] <- (dat[ as.matrix(upg[1:2]) ] + upg$count)

#  P1 P2 P3 P4 P5 P6
#A  1  0  0  0  0  0
#B  0  1  0  0  0  0
#C  0  0  2  0  0  1
#D  0  0  0  0  3  0
#E  2  0  0  0  0  0
#F  0  0  0  1  2  0
thelatemail
  • 91,185
  • 12
  • 128
  • 188
  • Dear thelatemail, I want to use this approach for a large dataset. Therefore i need to find a function to create the upg dataframe. Can you also help me with that? – Lisann Nov 21 '13 at 13:17
  • @Lisann - what do you wish to create the `upg` data.frame from? Would it just be the `P1_upgrade`,`P3_upgrade` etc vectors? If so, see my edit for how you could do this. – thelatemail Nov 21 '13 at 22:46