I have:
keys = ["a", "b", "j"]
vals = [1, 42, 9]
and I want something like:
somedic = ["a"=>1, "b"=>42, "j"=>9]
i.e.
Dict{String,Int64} with 3 entries:
"j" => 9
"b" => 42
"a" => 1
But how??
Keys & Values to Dict
ks = ["a", "b", "j"] # keys
vals = [1, 42, 9] # values
thedict = Dict(zip(ks, vs))
# or using broadcast syntax, which looks quite nice IMO (though
# does create a temporary Vector of key=>value pairs)
thedict = Dict(ks .=> vals)
The returned Dict will be of type Dict{String, Int} (i.e. Dict{String, Int64} on my system), since keys is a Vector of Strings and vals is a Vector of Ints.
Specifying the Types
If you want to specify the types of the Dict's keys or values, e.g. AbstractString and Real, you can do:
Dict{AbstractString, Real}(zip(ks, vals))
Related aside: Pairs in a single Vector/Array
If you have pairs in a single array:
dpairs = ["a", 1, "b", 42, "j", 9]
you can do:
Dict(dpairs[i]=>dpairs[i+1] for i in 1:2:length(dpairs))
the same syntax as above applies to specify the respective types of the keys and values, e.g.:
Dict{Any, Number}(dpairs[i]=>dpairs[i+1] for i in 1:2:length(dpairs))
I don't know Julia -- but if Julia has a zip, then this should work : dict(zip(keys,vals)).
(confession: this is how one would do it in python).
I think the Julian way would be to use the vectorized .=> version
keys = ["a", "b", "j"]
vals = [1, 42, 9]
Dict(keys .=> vals)
This is equivalent to using broadcast(=>, x, y)
https://docs.julialang.org/en/v1/manual/arrays/#man-array-and-vectorized-operators-and-functions
Related
In R, I am trying to run an apply function on a column (a) in a dataframe and putting the result in a new column (b). The column (c) is of integer class and consists of integers 0 - 5.
My code is:
df$b <- apply(df, 1, FUN = function (x) if (x["a"] == 0) x["b"] = "a"
else if (x["a"] == 1) x["b"] = "b"
else if (x["a"] == 2) x["b"] = "c"
else if (x["a"] == 3) x["b"] = "d"
else if (x["a"] == 4) x["b"] = "e"
else x["b"] = "f")
When column a is of class integer, all the logicals fail so all rows in column b are assigned "f". However, when I change column a to character class using as.character(), the logicals evaluate correctly. Why is this the case?
From the R Docs
Note that x == 0 will not work in all cases.
This (I believe, please correct me if I'm wrong) is because the values you have in your comparisons are R numeric types. You can verify this by running:
# Assign an integer value to y
y = 5
# print the class name of variable
print(class(y))
The numeric type of a value is not equal to the integer type of the value, but when you convert it into a character, the R comparison automatically converts the value to a numeric for you, using the unicode values of the character vector.
This specific code can be repaired in multiple ways. For what you seem to be doing, an apply function similar to the following might be a more readable solution:
values <- c("a", "b", "c", "d", "e")
df$b <- ifelse( a > 4, "f", values[a + 1])
See the vectorized ifelse documentation
x <- c(1, "a")
This is code for creating a vector in R , and if you print the value you get
"1" "a"
I need to know why the data type of 1 was changed to string? Any reason . Thanks in advance. Basically i need to know how does R performs coercion
As per ?c:
All arguments are coerced to a common type which is the type of the returned value, and all attributes except names are removed.
The output type is determined from the highest type of the components in the hierarchy:
NULL < raw < logical < integer < double < complex < character < list < expression.
Therefore:
c(1, "a")
#[1] "1" "a"
c(1, NULL)
#[1] 1
c(F, "a")
#[1] "FALSE" "a"
I am trying to determine how to assign variable a values stored in a vector to a series of variable names stored in a character vector in R?
Here is a toy example of what I'm trying to do: I would like to have ultimately have the values 1, 2, and 3, stored in the variables A, B, and C respectively, so that print(A) returns 1, print(B) returns 2, etc. However, I would like to store the variables A, B, and C as character values in a vector called my_variables . So:
my_variables <-c("A", "B", "C")
and I have the values 1, 2, 3, stored in a vector called my_values:
my_values <-1:3
I tried to use this, but it didn't quite work the way I wanted:
assign(my_variables, my_values)
This simply assigns "A" "B" "C" to the variable my_variables, but nothing is assigned to the variable A.
I can accomplish what I want to do with an array, but I wonder if there is a more efficient way to do this with vectorized operations? Is there a better way to approach this than using a loop?
assign is not vectorized, so you can use Map here specifying the environment.
Map(function(x, y) assign(x, y, envir = .GlobalEnv), my_variables, my_values)
A
#[1] 1
B
#[1] 2
C
#[1] 3
However, it is not a good practice to have such variables in the global environment.
Use a named vector :
name_vec <- setNames(my_values, my_variables)
name_vec
#A B C
#1 2 3
Or named list as.list(name_vec).
This will do the trick
val = 1:3
var = LETTERS[1:3]
l = as.list(val)
names(l) = var
list2env(l, envir = environment())
I'm looking for mutate_if() from R's dplyr. For example, how could I select the Int64 columns and convert them to Float?
using DataFrames
df = DataFrame(A = [72, 38, 54],
B = [1, 2, 3],
C = ["red", "blue", "green"])
# convert integer columns to decimal columns without selecting them by name
df
Here it is. The code converts columns with any integer number types (such as Int64, Int32) to a Float64.
for col in findall(x -> x <:Integer, eltypes(df))
df[!, col] = Float64.(df2[!, col])
end
I have vector
a <- c(2, 1, 1, 2)
and I want to replace each unique value with another unique value. For instance, I want 2 -> 'a' and 1 -> 'b' to create a vector with the same order like this:
c <- c('a', 'b', 'b', 'a')
I tried something this, but it didn't work:
replace(a, a %in% unique(a), b)
I want to avoid manually going to all unique values to generalize in case a is large. The replacement strings are just examples. The solution should also generalize to completely different strings
or values. E.g.: 2 -> 'Walter' and 1 -> 'Getrude'.
We can use match to get a numeric index and then replace based on it (using base R)
c('a', 'b')[match(a, unique(a))]
#[1] "a" "b" "b" "a"
One way to proceed here would be to define two data frames, one for the starting values and the other for the values to be mapped:
library(plyr)
df1 <- data.frame(a=c(2, 1, 1, 2))
df2 <- data.frame(a=c(1, 2), value=c('a', 'b'), stringsAsFactors=FALSE)
result <- join(df1, df2)$value
result
[1] "b" "a" "a" "b"
Having a dedicated data frame or table for mapping the values is probably a good long term strategy.