Reputation: 5088
I am trying to apply values of a vector over a list of character vectors using lapply and a hand-crafted function that contains multiple for-loops. Argh! Essentially what I have is a list of character vectors that looks like this (filename_lists3
):
$`809`
[1] "rakelib/blueprint.rb" "projects/daedalus/daedalus.rb"
$`859`
[1] "README"
...
and a named, numeric vector that looks like this (degree_list
):
projects/daedalus/daedalus.rb rakelib/blueprint.rb
1 5
README README.mdown
6 1
...
What I want to do is to match the character strings in filename_list3
to those in names(degree_list)
, and when they are the same, replace the character string in filename_list3
with the integer in degree_list
.
Here is my code:
dput(filename_lists3[1:10])
structure(list(`809` = c("rakelib/blueprint.rb", "projects/daedalus/daedalus.rb"
), `859` = "README", `957` = "spec/debugger/spec_helper.rb",
`1007` = c("README.mdown", "README"), `1038` = "spec/ruby/core/file/stat/setgid_spec.rb",
`1099` = c("vm/test/test_embedding.hpp", "vm/embed.c", "vm/api/embed.h"
), `1179` = c("vm/capi/module.cpp", "kernel/common/module19.rb",
"kernel/common/module18.rb"), `1235` = c("vm/builtin/thread.hpp",
"vm/builtin/thread.cpp", "kernel/common/thread.rb", "kernel/bootstrap/thread.rb"
), `1390` = "spec/ruby/core/marshal/dump_spec.rb", `1422` = c("spec/tags/19/ruby/core/module/constants_tags.txt",
"kernel/common/module19.rb", "kernel/common/module18.rb",
"kernel/common/module.rb")), .Names = c("809", "859", "957",
"1007", "1038", "1099", "1179", "1235", "1390", "1422"))
dput(degree_list[1:10])
structure(c(1, 5, 6, 1, 2, 2, 2, 5, 7, 2), .Names = c("projects/daedalus/daedalus.rb",
"rakelib/blueprint.rb", "README", "README.mdown", "vm/api/embed.h",
"vm/embed.c", "vm/test/test_embedding.hpp", "kernel/common/module18.rb",
"kernel/common/module19.rb", "vm/capi/module.cpp"))
as well as the function and the lapply call:
insert_sna_stat <- function(x, input = degree_list){
for (i in 1:length(x)){
for (n in 1:length(input))
if (names(input)[n] == x[i])
x[i] <- input[n] else
x[i] <- x[i]
}
}
lapply(filename_lists3, insert_sna_stat)
which at this point just generates null. What is going wrong here? How can I modify it to do what I described above?
Upvotes: 2
Views: 125
Reputation: 121568
I think you it is better to use merge
here. But, first you should transform your lists to data.frames.
D1 <- do.call(rbind,lapply(seq_along(filename_lists),
function(i) data.frame(name=filename_lists[[i]],
id = names(filename_lists)[i])))
D2 <- as.data.frame(degree_list)
D2$name <- rownames(D2)
merge(D1,D2,all.x=TRUE)
# name id degree_list
# 1 projects/daedalus/daedalus.rb 809 1
# 2 rakelib/blueprint.rb 809 5
# 3 README 859 6
# 4 README 1007 6
# 5 spec/debugger/spec_helper.rb 957 NA
# 6 README.mdown 1007 1
# 7 spec/ruby/core/file/stat/setgid_spec.rb 1038 NA
# 8 vm/api/embed.h 1099 2
# 9 vm/embed.c 1099 2
# 10 vm/test/test_embedding.hpp 1099 2
# 11 kernel/common/module18.rb 1179 5
# 12 kernel/common/module18.rb 1422 5
# 13 kernel/common/module19.rb 1179 7
# 14 kernel/common/module19.rb 1422 7
# 15 vm/capi/module.cpp 1179 2
# 16 kernel/bootstrap/thread.rb 1235 NA
# 17 kernel/common/thread.rb 1235 NA
# 18 vm/builtin/thread.cpp 1235 NA
# 19 vm/builtin/thread.hpp 1235 NA
# 20 spec/ruby/core/marshal/dump_spec.rb 1390 NA
# 21 kernel/common/module.rb 1422 NA
# 22 spec/tags/19/ruby/core/module/constants_tags.txt 1422 NA
Upvotes: 0
Reputation: 13372
You can use rapply
:
> rapply(filename_lists3, function(x) ifelse(x %in% names(degree_list), degree_list[x], x), how='replace')
$`809`
[1] 5 1
$`859`
[1] 6
$`957`
[1] "spec/debugger/spec_helper.rb"
$`1007`
[1] 1 6
$`1038`
[1] "spec/ruby/core/file/stat/setgid_spec.rb"
$`1099`
[1] 2 2 2
$`1179`
[1] 2 7 5
$`1235`
[1] "vm/builtin/thread.hpp" "vm/builtin/thread.cpp"
[3] "kernel/common/thread.rb" "kernel/bootstrap/thread.rb"
$`1390`
[1] "spec/ruby/core/marshal/dump_spec.rb"
$`1422`
[1] "spec/tags/19/ruby/core/module/constants_tags.txt"
[2] "7"
[3] "5"
[4] "kernel/common/module.rb"
Upvotes: 2
Reputation: 57210
You can use match
function :
res <- lapply(filename_lists3, function(x){
m <- match(x,names(degree_list))
x[!is.na(m)] <- degree_list[m[!is.na(m)]]
return(x)
})
##### results
> res
$`809`
[1] "5" "1"
$`859`
[1] "6"
$`957`
[1] "spec/debugger/spec_helper.rb"
$`1007`
[1] "1" "6"
$`1038`
[1] "spec/ruby/core/file/stat/setgid_spec.rb"
$`1099`
[1] "2" "2" "2"
$`1179`
[1] "2" "7" "5"
$`1235`
[1] "vm/builtin/thread.hpp" "vm/builtin/thread.cpp" "kernel/common/thread.rb" "kernel/bootstrap/thread.rb"
$`1390`
[1] "spec/ruby/core/marshal/dump_spec.rb"
$`1422`
[1] "spec/tags/19/ruby/core/module/constants_tags.txt" "7"
[3] "5" "kernel/common/module.rb"
Upvotes: 1
Reputation: 66834
You can lapply
over your filename list and use the values to subset the degree list. If there is no match you would get NA, so wrap around and ifelse
to return the original values in such cases.
lapply(filename_lists3, function(x) ifelse(is.na(degree_list[x]),x,degree_list[x]))
$`809`
rakelib/blueprint.rb projects/daedalus/daedalus.rb
5 1
$`859`
README
6
$`957`
<NA>
"spec/debugger/spec_helper.rb"
$`1007`
README.mdown README
1 6
$`1038`
<NA>
"spec/ruby/core/file/stat/setgid_spec.rb"
$`1099`
vm/test/test_embedding.hpp vm/embed.c
2 2
vm/api/embed.h
2
$`1179`
vm/capi/module.cpp kernel/common/module19.rb kernel/common/module18.rb
2 7 5
$`1235`
<NA> <NA>
"vm/builtin/thread.hpp" "vm/builtin/thread.cpp"
<NA> <NA>
"kernel/common/thread.rb" "kernel/bootstrap/thread.rb"
$`1390`
<NA>
"spec/ruby/core/marshal/dump_spec.rb"
$`1422`
<NA>
"spec/tags/19/ruby/core/module/constants_tags.txt"
kernel/common/module19.rb
"7"
kernel/common/module18.rb
"5"
<NA>
"kernel/common/module.rb"
Upvotes: 1