Reputation: 351
My data frame looks like that:
df <- data.frame(INFO=c("A;B;C", "B;A;C"), METRICS=c("1;2;3", "4;5;6"))
df
INFO METRICS
1 A;B;C 1;2;3
2 B;A;C 4;5;6
I am trying to catch the value of 'A' for each line using apply()
and store the resulting vector in a new column of my original data frame:
df$M1 <- apply(
df,
1,
function(x){
info <- unlist(strsplit(x[1], ";"))
metric <- unlist(strsplit(x[2], ";"))
for(i in 1:3){
ifelse(
info[i]=="A",
metric[i],
"."
)
}
}
)
In order to get the following result:
df
INFO METRICS M1
1 A;B;C 1;2;3 1
2 B;A;C 4;5;6 5
But the new column is not created.
Upvotes: 2
Views: 66
Reputation: 39858
You can also try grepRaw()
:
ind <- sapply(df$INFO, grepRaw, pattern = "A", fixed = TRUE)
substring(df$METRICS, ind, ind)
[1] "1" "5"
Upvotes: 1
Reputation: 51582
A vectorized way to do it is to unlist after spliting and make it a named vector, i.e.
i1 <- setNames(unlist(strsplit(as.character(df$METRICS), ';')),
unlist(strsplit(as.character(df$INFO), ';')))
then simply,
i1[names(i1) == 'A']
# A A
#"1" "5"
Or add it to your data frame,
df$M1 <- i1[names(i1) == 'A']
# INFO METRICS M1
#1 A;B;C 1;2;3 1
#2 B;A;C 4;5;6 5
Upvotes: 1
Reputation: 101044
Maybe you can try the apply
like below
df$M1<-apply(df, 1, function(x) {
unlist(strsplit(x[2],split = ";"))[unlist(strsplit(x[1],";"))=="A"]
})
such that
> df
INFO METRICS M1
1 A;B;C 1;2;3 1
2 B;A;C 4;5;6 5
Upvotes: 1
Reputation: 388807
We can split the string on ";"
and use mapply
to get the corresponding value of METRICS
where INFO == "A"
.
df$M1 <- mapply(function(x, y) y[x == "A"], strsplit(df$INFO, ";"),
strsplit(df$METRICS, ";"))
df
# INFO METRICS M1
#1 A;B;C 1;2;3 1
#2 B;A;C 4;5;6 5
data
Make sure the data is read as characters and not as factors.
df <- data.frame(INFO=c("A;B;C", "B;A;C"), METRICS=c("1;2;3", "4;5;6"),
stringsAsFactors = FALSE)
Upvotes: 1