Eugene Brown
Eugene Brown

Reputation: 4362

Conditionally filling rows of a data frame

I have a data frame of this structure which I would like to populate:

    V1      V2  V3  V4  V5  V6  V7  V8
1   ID_CODE 0   0   0   0   0   0   0
2   THIS    0   0   0   0   0   0   0
3   ISAROW  0   0   0   0   0   0   0
4   01      0   0   0   0   0   0   0
5   02      0   0   0   0   0   0   0
6   03      0   0   0   0   0   0   0
7   ID_CODE 0   0   0   0   0   0   0
8   THESE   0   0   0   0   0   0   0
9   ARE     0   0   0   0   0   0   0
10  MORE    0   0   0   0   0   0   0
11  ROWS    0   0   0   0   0   0   0
12  01      0   0   0   0   0   0   0
13  02      0   0   0   0   0   0   0
14  03      0   0   0   0   0   0   0
15  ROW     0   0   0   0   0   0   0

And this data frame with the numbers to populate it:

  V2_1 V2_2 V2_3 V2_4 V2_5 V2_6 V2_7
1 786  786  786  786  786  786  786
2 786  786  786  786  786  786  786
3 78   78   78   78   78   78   78
4 78   78   78   78   78   78   78
5 78   78   78   78   78   78   78
6 78   78   78   78   78   78   78

These numbers are to go into columns V2:V8 and only in rows in which V1 is a number. The rows in which V1 is a string are to stay as zeroes.

Upvotes: 5

Views: 239

Answers (2)

akrun
akrun

Reputation: 887881

We could create an index based on the presence of numbers in "V1" column of "df1", use that index to subset "df1", multiply that with "df2" after adding "1" (assuming that the dimensions will be the same)

indx <- grep("^\\d+$", df1$V1)
df1[indx,-1] <- df1[indx,-1]+1 *df2
df1
#       V1  V2  V3  V4  V5  V6  V7  V8
#1  ID_CODE   0   0   0   0   0   0   0
#2     THIS   0   0   0   0   0   0   0
#3   ISAROW   0   0   0   0   0   0   0
#4       01 786 786 786 786 786 786 786
#5       02 786 786 786 786 786 786 786
#6       03  78  78  78  78  78  78  78
#7  ID_CODE   0   0   0   0   0   0   0
#8    THESE   0   0   0   0   0   0   0
#9      ARE   0   0   0   0   0   0   0
#10    MORE   0   0   0   0   0   0   0
#11    ROWS   0   0   0   0   0   0   0
#12      01  78  78  78  78  78  78  78
#13      02  78  78  78  78  78  78  78
#14      03  78  78  78  78  78  78  78
#15     ROW   0   0   0   0   0   0   0

Upvotes: 4

Rich Scriven
Rich Scriven

Reputation: 99371

If df1 is the original and df2 the replacement, then we can use Map to replace the subset.

## find the rows with only digits in the first column
rows <- grepl("^\\d+$", df1$V1)
## replace the subset with 'df2'
df1[rows, -1] <- Map("[<-", df1[rows, -1], df2)
df1
#         V1  V2  V3  V4  V5  V6  V7  V8
# 1  ID_CODE   0   0   0   0   0   0   0
# 2     THIS   0   0   0   0   0   0   0
# 3   ISAROW   0   0   0   0   0   0   0
# 4       01 786 786 786 786 786 786 786
# 5       02 786 786 786 786 786 786 786
# 6       03  78  78  78  78  78  78  78
# 7  ID_CODE   0   0   0   0   0   0   0
# 8    THESE   0   0   0   0   0   0   0
# 9      ARE   0   0   0   0   0   0   0
# 10    MORE   0   0   0   0   0   0   0
# 11    ROWS   0   0   0   0   0   0   0
# 12      01  78  78  78  78  78  78  78
# 13      02  78  78  78  78  78  78  78
# 14      03  78  78  78  78  78  78  78
# 15     ROW   0   0   0   0   0   0   0

Or, another way would be to use replace()

df1[rows, -1] <- Map(function(x, y) replace(x, rows, y), df1[-1], df2)

Upvotes: 4

Related Questions