I'm trying to convert some R code script into C# code via RDotNet Library.
I was able to convert a big part but there's an issue while creating data.table in C#.
Above is my code example:
Dictionary<string, List<string>> myDic = new Dictionary<string, List<string>>();
// populate the dictionary
var colNames = new List<string>() { "col1", "col2"};
IEnumerable[] columns = new IEnumerable[2];
columns[0] = myDic.Keys;
columns[1] = myDic.Values;
var mydata = engine.CreateDataFrame(columns.ToArray(), colNames.ToArray(), stringsAsFactors: false);
when i use the variable mydata, I got an exception
Cannot convert type System.Collections.Generic.List`1[System.String][] to an R vector
Are you sure you want to create a dataframe column that contains a list of strings in each cell? It's not how you create a dataframe in R. The code below works when you replace Dictionary<string,List<string>> with Dictionary<string,string>.
Dictionary<string, string> myDic = new Dictionary<string, string>() {
{ "a","aaaa"},
{ "b","bbbb"},
{ "c","cccc"}
};
// populate the dictionary
var colNames = new List<string>() { "col1", "col2" };
IEnumerable[] columns = new IEnumerable[2];
columns[0] = myDic.Keys.ToArray();
columns[1] = myDic.Values.ToArray();
REngine engine = REngine.GetInstance();
var mydata = engine.CreateDataFrame(columns, colNames.ToArray(), stringsAsFactors: false);
Related
I am writing a csv file using CSV helper
var entries = new List<ExpandoObject>();
ExpandoObject dynamic = GetVersionInfo(list.Id.ToString(), $"{file.MajorVersion}.0");
entries.Add(dynamic);
using (var writer = new StreamWriter("file.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
var writeList = new List<dynamic>();
writeList.AddRange(entries);
csv.WriteRecords(writeList);
}
this code works fine and I can see a csv file has been created but columns data is not in correct order. for example
Version Date is being written in Document Owner column. Reason for this mismatch is that I am using expando objects and order of the properties in the expando object is not in a proper sequence.
In first object Version Date is at number 3 in expando object while it is at number 4 in 2nd object.
I tried to sort the properties with this method but I get error in generating the csv, for example
writeList.AddRange(entries.Select(x => x.OrderByDescending(y => y.Key).ToList()));
csv.WriteRecords(writeList); //exception here
Exception I get is
Types that inherit IEnumerable cannot be auto mapped. Did you accidentally call GetRecord or WriteRecord which acts on a single record instead of calling GetRecords or WriteRecords which acts on a list of records?
how can I sort and also write a collection of Expando objects in a CSV file?
The problem with entries.Select(x => x.OrderByDescending(y => y.Key).ToList() is you no longer have a List<ExpandoObject>, but IEnumerable<List<KeyValuePair<String,Object>>> There might be a more concise way to do this, but you need to get it back to List<ExpandoObject>.
void Main()
{
var entries = new List<ExpandoObject>();
dynamic obj1 = new ExpandoObject();
obj1.Version = 11;
obj1.Modified = new DateTime(2017,9,18);
obj1.VersionDate = new DateTime(2016,6,29);
obj1.DocumentOwner = "Unknown";
dynamic obj2 = new ExpandoObject();
obj2.Version = 1;
obj2.Modified = new DateTime(2021, 3, 17);
obj2.DocumentOwner = "Emergency Management Plan";
obj2.VersionDate = new DateTime(2019, 1, 4);
entries.Add(obj1);
entries.Add(obj2);
entries = SortEntries(entries);
//using (var writer = new StreamWriter("path\\to\\file.csv"))
using (var csv = new CsvWriter(Console.Out, CultureInfo.InvariantCulture))
{
var writeList = new List<dynamic>();
writeList.AddRange(entries);
csv.WriteRecords(writeList);
}
}
public List<ExpandoObject> SortEntries(IList<ExpandoObject> entries)
{
var newList = new List<ExpandoObject>();
foreach (var entry in entries)
{
var x = new ExpandoObject() as IDictionary<string, Object>;
var sorted = entry.OrderByDescending(y => y.Key);
foreach (var item in sorted)
{
x.Add(item.Key, item.Value);
}
newList.Add((ExpandoObject)x);
}
return newList;
}
var ctsDB = mooe.Files66.ToList();
Dictionary<string, string> mappedfields = new Dictionary<string, string>();
Dictionary<string, string> ctsfieldsValue = new Dictionary<string, string>();
for (int i = 0; i < ctsDB.Count; i++)
{
foreach(var item in mappedfields) {
// this line returns the item.key string not the value of it.
// item.key is the column name
var rowValue = mooe.Files66.Select(k = >item.Key).ToList();
// ctsfieldsValue.Add(item.Value, rowValue);
ctsfieldsValue.ToList();
}
}
I want to iterate through ctsDB List and get the row value of a specific
column like this:
if ctsDB [i] = fileID Field612 Fiel613
and I have these column names in the value field of ctsfieldsValue.
I want to iterate on ctsDB[i] to get the value of column Field612 only.
Can anyone provide a thought?
var ctsDB = mooe.Files66.ToList();
var mappedfields = new Dictionary<string, string>(); // I assume this is not empty in your real code.
var ctsfieldsValue = new List<Dictionary<string, string>>();
foreach (var row in ctsDB)
{
var d = new Dictionary<string, string>();
foreach (var mapping in mappedfields)
{
var v = row[mapping.Key]; //throws if not found
d[mapping.Value] = v;
}
ctsfieldsValue.Add(d);
}
I'm new to Json.net, so I'm not sure if I'm doing this the right / best way, but I can't figure this out:
I'm creating an output JObject:
JObject joOutput = new JObject();
Now, I have a list of paths to values:
a.b.c = 5
a.b.d = 7
a.c.q = 8
So I want to populate the joOutput object in the obvious way using that hierarchy.
I can't seem to find a way to set the value by path, obviously creating the path along the way if it doesn't exist.
I'm trying to split the path on the .'s and create the nodes, but I can't even get that far as the api is very confusing.
Can you point me in the right direction?
Thanks!
string a = #"{""b"": {""c"":5, ""d"":7}, ""c"": {""q"":8}}";
JObject joObject = JObject.Parse(a);
UPDATE:
var B = new JObject();
B.Add("c", 5);
B.Add("d", 7);
var C = new JObject();
C.Add("q", 8);
JObject A = new JObject();
A.Add("b", B);
A.Add("c", C);
UPDATE2, for completeness, here is Vladimir's method:
var B = new Dictionary<string, int> { ["c"] = 5, ["d"] = 7 };
var C = new Dictionary<string, int> { ["q"] = 5, ["8"] = 7 };
var A = new Dictionary<string, object> { ["b"] = B, ["c"] = C };
var AA = JObject.FromObject(A);
Try to solve your problem by using Dictionary with string key and object value.
Dictionary<string,object> myJsonObj = new Dictionary<string, object>;
Each element inside can be also same dictionary.
I want to create a array of list which will contain a string and a list of arrays.
example:
I want like this one.
list(0) --- string value list(0) ---list(0) - string value
list(0) ----list(1) - string value
list(1) --- string value list(1) ---list(0) - string value
list(1) ----list(1) - string value
and so on..
how will i declare?
i tried:
List<List<String>> list = new List<List<string>>(); // but it didn't work.
List<string[]> arrayList = new List<string[]>(); // again it didn't work..
is this possible to declare?
if so how?
Isnt this a Dictionary<string, string[]>?
var x = new Dictionary<string, string[]>();
x.Add("string1", new string[] {"a", "b", "c"})
Then you can have a list of that dictionary.
var list = new List<Dictionary<string, string[]>>();
list.Add(x);
Does this work for you?
public class Tree<T> : List<Tree<T>>
{
public Tree(T value) { this.Value = value; }
public T Value { get; set; }
}
It's not an array, but a list, but it's much the same structure.
You can then assign it like this:
var trees = new []
{
new Tree<string>("Branch 1")
{
new Tree<string>("Leaf 1.1"),
new Tree<string>("Leaf 1.2"),
},
new Tree<string>("Branch 2")
{
new Tree<string>("Leaf 2.1"),
new Tree<string>("Leaf 2.2"),
},
};
As I can see in your data structure you've asked for A List containing two List's and all of them are of same string type then you should go with Dictionary. As a List can of of single type and you can add a single value to it at a time. Try Dictionary,
Dictionary<string, string> dictionary = new Dictionary<string, string>();
or if you want a Dictionary containing List of string,
Dictionary<List<string>, List<string>> dictionary = new Dictionary<List<string>, List<string>>();
try this
List<List<String>> str_2d_list = new List<List<String>>();
List<String> l1 = new List<string>();
l1.Add("l1.string1");
l1.Add("l1,string2");
List<String> l2 = new List<string>();
l2.Add("l2.string1");
l2.Add("l2,string2");
str_2d_list.Add(l1);
str_2d_list.Add(l2);
if you want to create an array of a string and a list, use the second way in the code. but if you want a list of list use first way in the code.
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main(string[] args)
{
// an example of list of strings
List<string> names = new List<string>();
names.Add("Mike");
names.Add("Sarah");
List<string> families = new List<string>();
families.Add("Ahmadi");
families.Add("Ghasemi");
// 1st way
List<List<string>> outsideList = new List<List<string>>();
outsideList.Add(names);
outsideList.Add(families);
// 2nd way
Dictionary<string, List<string>> d = new Dictionary<string, List<string>>();
d.Add("first", names);
d.Add("second", families);
// how to access list<list<>>
foreach (List<string> list in outsideList)
{
foreach (string s in list)
Console.WriteLine(s);
}
// how to access list inside dictionary
foreach (List<string> list in d.Values)
{
foreach (string s in list)
Console.WriteLine(s);
}
}
}
}
I have a unique double corresponding to a variation of three strings. I want to populate a dictionary or something such that I can call something like dict[key1][key2][key3] and get the value.
I've tried a whole bunch of things like
Dictionary<string, Dictionary<string, double>> dict = new Dictionary<string, Dictionary<string, double>> {
{ "Foo", {"Bar", 1.2 } },
{ "Foo", {"Test", 3.4 } }
};
Which gives me syntax errors and errors like "Error 4 A namespace cannot directly contain members such as fields or methods"
And
Dictionary<double, Tuple<string, string>> dict = {
{1.23, "Blah", "Foo"}
};
Which gives me errors like "Error 1 Can only use array initializer expressions to assign to array types. Try using a new expression instead."
And
object dict = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
dict["k1"] = new Dictionary<string, Dictionary<string, string>>();
dict["k1"]["k2"] = new Dictionary<string, string>();
dict["k1"]["k2"]["k3"] = 3.5;
Which gives me syntax errors and errors like "Error 2 Invalid token '"k1"' in class, struct, or interface member declaration"
How should I go about this? Thanks in advance.
![enter image description here][1]
Edit: Trying Jonesy's code:
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string[] grades = { "Grade 1", "Grade 5", "Grade 8", "ASTM A325", "316 Stainless", "Monel", "Brighton Best 1960" };
string[] sizes = { "#1", "2", "3", "4", "5", "6", "8", "10", "12", "1/4", "5/16", "3/8", "7/16", "1/2", "9/16", "5/8", "3/4", "7/8", "1", "1-1/8", "1-1/4", "1-3/8", "1-1/2" };
var dict = new Dictionary<string, Dictionary<string, Dictionary<string, double>>>();
dict["k1"] = new Dictionary<string, Dictionary<string, double>>();
dict["k1"]["k2"] = new Dictionary<string, double>();
dict["k1"]["k2"]["k3"] = 3.5;
public Form1()
{
InitializeComponent();
}
your last attempt is close, you want:
var dict = new Dictionary<string, Dictionary<string, Dictionary<string, double>>>();
dict["k1"] = new Dictionary<string, Dictionary<string, double>>();
dict["k1"]["k2"] = new Dictionary<string, double>();
dict["k1"]["k2"]["k3"] = 3.5;
you want var instead of object
(or Dictionary<string, Dictionary<string, Dictionary<string, double>>> if you like scrolling)
and your very last string should be a double.
As I understood, you have data and want to perform lookup in it. Why can't you just use some database for that purpose?
But if you really want to hardcode all values, you can. Just don't initialize dictionary manually, make simplifications - parse data in runtime.
Something like this. (I suppose, that you are novice in c# programming, so I've created new Console Application and copy-pasted all the code for your convenience)
public class Program
{
// harcode all data as string
const string RawData =
"k11,k12,k13=3.4;" +
"k21,k22,k23=4.42;" +
"k31,k32,k33=5.91;" +
"k41,k42,k43=8.14;" +
"k51,k52,k53=4.13;" +
"k61,k62,k63=5.4";
static void Main(string[] args)
{
// create dictionary from hardcoded string
var data = ParseData();
// use Tuple as key for data lookup
var value = data[Tuple.Create("k11", "k12", "k13")];
// check, that value equals expected one
Debug.Assert(value == 3.4);
}
private static IDictionary<Tuple<string, string, string>, double> ParseData()
{
var parsedData =
RawData
.Split(';')
.Select(ParseRow)
.ToDictionary(x => x.Item1, x => x.Item2);
return parsedData;
}
private static Tuple<Tuple<string, string, string>, double> ParseRow(string row)
{
var parts = row.Split('=');
var coefficients = ParseCoefficients(parts[0]);
var value = Double.Parse(parts[1], CultureInfo.InvariantCulture);
return Tuple.Create(coefficients, value);
}
private static Tuple<string, string, string> ParseCoefficients(string row)
{
var coeffs = row.Split(',');
var result = Tuple.Create(coeffs[0], coeffs[1], coeffs[2]);
return result;
}
}
As another simplification, you can use custom class as dictionary key instead of nested dictionaries. Write your own(pay attention, that it should override equality members Equals and GetHashCode), or use something from base class library. Tuple<string, string, string> is the perfect one.