Oscar
Oscar

Reputation: 457

R add vector content to data frame index

I would like to add the content of a vector to a data frame. For example, I have a vector like:

1, 2, 1, 1, 2, 4

And a data frame like:

Name1 Name2 Name3 Name4 Name5 Name6
    3     2     2     0     3     1

And I would like to count the numbers that appear in the vector, and add that number to that column index in de data frame, so in this example I would get a data frame like:

Name1 Name2 Name3 Name4 Name5 Name6
    6     4     2     1     3     1

Because there are three 1, two 2, and one 4 in the vector.

I don't know if I have been clear enough, but thanks!

Upvotes: 4

Views: 445

Answers (5)

markus
markus

Reputation: 26343

Because there are three 1, two 2, and one 4 in the vector.

You could convert your vector to a factor with levels reaching from 1 to the number of columns in your data. Then use table to count the number of appearances and add it to your data frame.

df + table(factor(vec, levels = 1:ncol(df)))
#  Name1 Name2 Name3 Name4 Name5 Name6
#1     6     4     2     1     3     1

data

df <- structure(list(Name1 = 3L, Name2 = 2L, Name3 = 2L, Name4 = 0L, 
    Name5 = 3L, Name6 = 1L), .Names = c("Name1", "Name2", "Name3", 
"Name4", "Name5", "Name6"), class = "data.frame", row.names = c(NA, 
-1L))

vec <- c(1, 2, 1, 1, 2, 4)

Upvotes: 2

Shapour
Shapour

Reputation: 21

There is most probably a function that does the same thing; however, I think this code might work for you.

A test set of a vector and a data frame,

o<-data.frame(round(runif(5,min = 1,max = 5 )))
q<-round(runif(5,min = 1,max = 5))

And here is a loop for counting the numbers in the vector set and adding the value of data frame set to the counted number.

for (i in 1:dim(o)[1]){
  j=1
  while (j<=dim(o)[1]) {
  if(i==q[j]){o[i,1]<-o[i,1]+1}
    j<-j+1
  }}

Upvotes: 1

Lennyy
Lennyy

Reputation: 6132

df + replace(vec, 1:6, tabulate(vec, 6))

  Name1 Name2 Name3 Name4 Name5 Name6
1     6     4     2     1     3     1

Ore more generally, with some explanation:

df + replace(vec, 1:dim(df)[2], tabulate(vec, dim(df)[2]))
    #replace values in vec
    #list of values to be replaced: 1:6 (since you have 6 columns)
    #replaced by the occurence of each value in vec (using tabulate with nbins ensures each value between 1 and 6 is in the replacement list, with zeroes for 3, 5 and 6)   
    #finally, add it to df

DATA:

vec <- c(1, 2, 1, 1, 2, 4)

df <- read.table(text = "
                 Name1 Name2 Name3 Name4 Name5 Name6
    3     2     2     0     3     1", h = T)

Upvotes: 2

989
989

Reputation: 12937

If the column names are like you stated in your question, then something like:

tb <- table(vec)
cols <- paste0("Name", names(tb))
df[cols] <- df[cols] + tb

where vec is your vector and df your data frame.

In case the column names do not matter but the index of the columns then replace cols with

cols <- as.numeric(names(tb))

Upvotes: 2

milan
milan

Reputation: 4970

You can use a loop. Inside use which to identify matches and length to count the number of occurrences.

a <- NULL
for(i in 1:length(v)){
  a <- c(a,length(which(v==i)))
}

df+a

  Name1 Name2 Name3 Name4 Name5 Name6
1     6     4     2     1     3     1

Read your data like this.

v <- c(1, 2, 1, 1, 2, 4)

df <- read.table(text="
Name1 Name2 Name3 Name4 Name5 Name6
    3     2     2     0     3     1", header=T)     

Upvotes: 0

Related Questions