2

I am trying to add a new column (slot) to a data.frame, depending on the row value of id. The short representative data is as following.

        id                Cap         Rs       R_inv
  257   464A485SSEE3    1.41E-10    736665.125  1.36E-06
  258   464A485SSEE3    1.30E-10    364822.6875 2.74E-06
  289   464A485TSEB2    1.44E-10    111996.1016 8.93E-06
  290   464A485TSEB2    1.33E-10    108541      9.21E-06

I think we could write a loop function to add new column. But I hope to learn simple function such as cbind or raw$slot<-???

royhowie
  • 11,075
  • 14
  • 50
  • 67
Rick
  • 229
  • 1
  • 3
  • 11
  • I am trying to add raw$slot depends row$id value such as raw$id=="464A485SSEE3" add raw$slot<-"slot 1", raw$id=="464A485TSEB2" add raw$slot<-"slot 2". – Rick Nov 06 '14 at 05:54

2 Answers2

1

Try

 raw$slot <- with(raw, paste0("slot",as.numeric(factor(id))))
 raw
 #              id      Cap       Rs    R_inv  slot
 #257 464A485SSEE3 1.41e-10 736665.1 1.36e-06 slot1
 #258 464A485SSEE3 1.30e-10 364822.7 2.74e-06 slot1
 #289 464A485TSEB2 1.44e-10 111996.1 8.93e-06 slot2
 #290 464A485TSEB2 1.33e-10 108541.0 9.21e-06 slot2

Or if the dataset is ordered by id, you could also do

 raw$slot <- paste0("slot",cumsum(c(TRUE,raw$id[-1]!=raw$id[-nrow(raw)])))

Update

If you need some custom labels, you can convert the id to factor (if it is not) and specify the labels that you want

raw$slot <- with(raw,  as.character(factor(id, labels=c('split6', 'split9'))) )
raw$slot
#[1] "split6" "split6" "split9" "split9"

Or just make use of numeric index by converting the factor to numeric and use the vector of names on that index. Here, you need to know the order of levels before you do this.

 with(raw, c('split6', 'split9')[as.numeric(factor(id))])
 #[1] "split6" "split6" "split9" "split9"

data

 raw <- structure(list(id = c("464A485SSEE3", "464A485SSEE3", "464A485TSEB2", 
 "464A485TSEB2"), Cap = c(1.41e-10, 1.3e-10, 1.44e-10, 1.33e-10
 ), Rs = c(736665.125, 364822.6875, 111996.1016, 108541), R_inv = c(1.36e-06, 
 2.74e-06, 8.93e-06, 9.21e-06)), .Names = c("id", "Cap", "Rs", 
 "R_inv"), class = "data.frame", row.names = c("257", "258", "289", "290"))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thanks a lot akrun! It is really helpful tip for beginner. Let me ask a new situation. What if I want to do raw$slot<-"split6" if raw$id=="464A485SSEE3" and raw$slot<-"split9" if raw$id=="464A485TSEB2"? I have a long table with ~5-10 different raw$id. – Rick Nov 06 '14 at 06:23
1

If you have a long table, probably could consider using "join" function of "dplyr" package.

# First, here is your data:
df <- structure(list(id = structure(c(1L, 1L, 2L, 2L), .Label = c("464A485SSEE3", 
"464A485TSEB2"), class = "factor"), Cap = c(1.41e-10, 1.3e-10, 
1.44e-10, 1.33e-10), Rs = c(736665.125, 364822.6875, 111996.1016, 
108541), R_inv = c(1.36e-06, 2.74e-06, 8.93e-06, 9.21e-06)), .Names = c("id", 
"Cap", "Rs", "R_inv"), class = "data.frame", row.names = c("257", 
"258", "289", "290"))

#               id      Cap       Rs    R_inv
# 257 464A485SSEE3 1.41e-10 736665.1 1.36e-06
# 258 464A485SSEE3 1.30e-10 364822.7 2.74e-06
# 289 464A485TSEB2 1.44e-10 111996.1 8.93e-06
# 290 464A485TSEB2 1.33e-10 108541.0 9.21e-06


# Then create a matching table similar to below:
match_table <- structure(list(id = structure(1:2, .Label = c("464A485SSEE3", 
"464A485TSEB2"), class = "factor"), slot_no = structure(1:2, .Label = c("slot_1", 
"slot_2"), class = "factor")), .Names = c("id", "slot_no"), class = "data.frame", row.names = c(NA, 
-2L))

#             id slot_no
# 1 464A485SSEE3  slot_1
# 2 464A485TSEB2  slot_2

# Do joining
library(dplyr)
left_join(df, match_table)
#             id      Cap       Rs    R_inv slot_no
# 1 464A485SSEE3 1.41e-10 736665.1 1.36e-06  slot_1
# 2 464A485SSEE3 1.30e-10 364822.7 2.74e-06  slot_1
# 3 464A485TSEB2 1.44e-10 111996.1 8.93e-06  slot_2
# 4 464A485TSEB2 1.33e-10 108541.0 9.21e-06  slot_2
KFB
  • 3,501
  • 3
  • 15
  • 18