Is there an easier way to modify a value in a subsubsub record field in Erlang? - erlang

So I've got a fairly deep hierarchy of record definitions:
-record(cat, {name = '_', attitude = '_',}).
-record(mat, {color = '_', fabric = '_'}).
-record(packet, {cat = '_', mat = '_'}).
-record(stamped_packet, {packet = '_', timestamp = '_'}).
-record(enchilada, {stamped_packet = '_', snarky_comment = ""}).
And now I've got an enchilada, and I want to make a new one that's
just like it except for the value of one of the subsubsubrecords.
Here's what I've been doing.
update_attitude(Ench0, NewState)
when is_record(Ench0, enchilada)->
%% Pick the old one apart.
#enchilada{stamped_packet = SP0} = Ench0,
#stamped_packet{packet = PK0} = SP0,
#packet{cat = Tag0} = PK0,
%% Build up the new one.
Tude1 = Tude0#cat{attitude = NewState},
PK1 = PK0#packet{cat = Tude1},
SP1 = SP0#stamped_packet{packet = PK1},
%% Thank God that's over.
Ench0#enchilada{stamped_packet = SP1}.
Just thinking about this is painful. Is there a better way?

As Hynek suggests, you can elide the temporary variables and do:
update_attitude(E = #enchilada{stamped_packet = (P = #packet{cat=C})},
NewAttitude) ->
E#enchilada{stamped_packet = P#packet{cat = C#cat{attitude=NewAttitude}}}.
Yariv Sadan got frustrated with the same issue and wrote Recless, a type inferring parse transform for records which would allow you to write:
-compile({parse_transform, recless}).
update_attitude(Enchilada = #enchilada{}, Attitude) ->
Enchilada.stamped_packet.packet.cat.attitude = Attitude.

Try this:
update_attitude(E = #enchilada{
stamped_packet = (SP = #stamped_packet{
packet = (P = #packet{
cat = C
})})}, NewState) ->
E#enchilada{
stamped_packet = SP#stamped_packet{
packet = P#packet{
cat = C#cat{
attitude = NewState
}}}}.
anyway, structures is not most powerful part of Erlang.

Related

How to load Seurat Object into WGCNA Tutorial Format

As far as I can find, there is only one tutorial about loading Seurat objects into WGCNA (https://ucdavis-bioinformatics-training.github.io/2019-single-cell-RNA-sequencing-Workshop-UCD_UCSF/scrnaseq_analysis/scRNA_Workshop-PART6.html). I am really new to programming so it's probably just my inexperience, but I am not sure how to load my Seurat object into a format that works with WGCNA's tutorials (https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/).
Here is what I have tried thus far:
This tries to replicate datExpr and datTraits from part I.1:
library(WGCNA)
library(Seurat)
#example Seurat object -----------------------------------------------
ERlist <- list(c("CPB1", "RP11-53O19.1", "TFF1", "MB", "ANKRD30B",
"LINC00173", "DSCAM-AS1", "IGHG1", "SERPINA5", "ESR1",
"ILRP2", "IGLC3", "CA12", "RP11-64B16.2", "SLC7A2",
"AFF3", "IGFBP4", "GSTM3", "ANKRD30A", "GSTT1", "GSTM1",
"AC026806.2", "C19ORF33", "STC2", "HSPB8", "RPL29P11",
"FBP1", "AGR3", "TCEAL1", "CYP4B1", "SYT1", "COX6C",
"MT1E", "SYTL2", "THSD4", "IFI6", "K1AA1467", "SLC39A6",
"ABCD3", "SERPINA3", "DEGS2", "ERLIN2", "HEBP1", "BCL2",
"TCEAL3", "PPT1", "SLC7A8", "RP11-96D1.10", "H4C8",
"PI15", "PLPP5", "PLAAT4", "GALNT6", "IL6ST", "MYC",
"BST2", "RP11-658F2.8", "MRPS30", "MAPT", "AMFR", "TCEAL4",
"MED13L", "ISG15", "NDUFC2", "TIMP3", "RP13-39P12.3", "PARD68"))
tnbclist <- list(c("FABP7", "TSPAN8", "CYP4Z1", "HOXA10", "CLDN1",
"TMSB15A", "C10ORF10", "TRPV6", "HOXA9", "ATP13A4",
"GLYATL2", "RP11-48O20.4", "DYRK3", "MUCL1", "ID4", "FGFR2",
"SHOX2", "Z83851.1", "CD82", "COL6A1", "KRT23", "GCHFR",
"PRICKLE1", "GCNT2", "KHDRBS3", "SIPA1L2", "LMO4", "TFAP2B",
"SLC43A3", "FURIN", "ELF5", "C1ORF116", "ADD3", "EFNA3",
"EFCAB4A", "LTF", "LRRC31", "ARL4C", "GPNMB", "VIM",
"SDR16C5", "RHOV", "PXDC1", "MALL", "YAP1", "A2ML1",
"RP1-257A7.5", "RP11-353N4.6", "ZBTB18", "CTD-2314B22.3", "GALNT3",
"BCL11A", "CXADR", "SSFA2", "ADM", "GUCY1A3", "GSTP1",
"ADCK3", "SLC25A37", "SFRP1", "PRNP", "DEGS1", "RP11-110G21.2",
"AL589743.1", "ATF3", "SIVA1", "TACSTD2", "HEBP2"))
genes = c(unlist(c(ERlist,tnbclist)))
mat = matrix(rnbinom(500*length(genes),mu=500,size=1),ncol=500)
rownames(mat) = genes
colnames(mat) = paste0("cell",1:500)
sobj = CreateSeuratObject(mat)
sobj = NormalizeData(sobj)
sobj$ClusterName = factor(sample(0:1,ncol(sobj),replace=TRUE))
sobj$Patient = paste0("Patient", 1:500)
sobj = AddModuleScore(object = sobj, features = tnbclist,
name = "TNBC_List",ctrl=5)
sobj = AddModuleScore(object = sobj, features = ERlist,
name = "ER_List",ctrl=5)
#WGCNA -----------------------------------------------------------------
sobjwgcna <- sobj
sobjwgcna <- FindVariableFeatures(sobjwgcna, selection.method = "vst", nfeatures = 2000,
verbose = FALSE, assay = "RNA")
options(stringsAsFactors = F)
sobjwgcnamat <- GetAssayData(sobjwgcna)
datExpr <- t(sobjwgcnamat)[,VariableFeatures(sobjwgcna)]
datTraits <- sobjwgcna#meta.data
datTraits = subset(datTraits, select = -c(nCount_RNA, nFeature_RNA))
I then copy-paste the code as written in the WGCNA I.2a tutorial (https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/FemaleLiver-02-networkConstr-auto.pdf), and that all works until I get to this line in the I.3 tutorial (https://horvath.genetics.ucla.edu/html/CoexpressionNetwork/Rpackages/WGCNA/Tutorials/FemaleLiver-03-relateModsToExt.pdf):
MEList = moduleEigengenes(datExpr, colors = moduleColors)
Error in t.default(expr[, restrict1]) : argument is not a matrix
I tried converting both moduleColors and datExpr into a matrix with as.matrix(), but the error still persists.
Hopefully this makes sense, and thanks for reading!
So doing as.matrix(datExpr) right after datExpr <- t(sobjwgcnamat)[,VariableFeatures(sobjwgcna)] worked. I had been trying it right before MEList = moduleEigengenes(datExpr, colors = moduleColors)
and that didn't work. Seems simple but order matters I guess.

ELKI CSV parser problems

I have changed an .arff file to a .csv file in a tool in Weka.
But now I can't use the arffparser as parser in ELKI.
What parser should I then use? The default is NumberVectorLabelParser. But it gives me a ArrayIndexOutOfBoundsException:
Running: -verbose -verbose -dbc.in /home/db/lisbet/Datasets/without ids/try 2/calling them .txt using another parser/Lymphography_withoutdupl_norm_1ofn.csv -dbc.parser NumberVectorLabelParser -algorithm outlier.lof.LOF -lof.k 2 -evaluator outlier.OutlierROCCurve -rocauc.positive yes
Task failed
java.lang.ArrayIndexOutOfBoundsException: 47
at de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser.getTypeInformation(NumberVectorLabelParser.java:337)
at de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser.buildMeta(NumberVectorLabelParser.java:242)
at de.lmu.ifi.dbs.elki.datasource.parser.NumberVectorLabelParser.nextEvent(NumberVectorLabelParser.java:211)
at de.lmu.ifi.dbs.elki.datasource.bundle.MultipleObjectsBundle.fromStream(MultipleObjectsBundle.java:242)
at de.lmu.ifi.dbs.elki.datasource.parser.AbstractStreamingParser.asMultipleObjectsBundle(AbstractStreamingParser.java:89)
at de.lmu.ifi.dbs.elki.datasource.InputStreamDatabaseConnection.loadData(InputStreamDatabaseConnection.java:91)
at de.lmu.ifi.dbs.elki.database.StaticArrayDatabase.initialize(StaticArrayDatabase.java:119)
at de.lmu.ifi.dbs.elki.workflow.InputStep.getDatabase(InputStep.java:62)
at de.lmu.ifi.dbs.elki.KDDTask.run(KDDTask.java:108)
at de.lmu.ifi.dbs.elki.application.KDDCLIApplication.run(KDDCLIApplication.java:60)
at [...]
My .csv file looks like this:
'Lymphatics = deformed','Lymphatics = displaced','Lymphatics = arched','Lymphatics = normal','Block_of_affere = yes','Block_of_affere = no','Bl_of_lymph_c = no','Bl_of_lymph_c = yes','Bl_of_lymph_s = no','Bl_of_lymph_s = yes','By_pass = no','By_pass = yes','Extravasates = yes','Extravasates = no','Regeneration_of = no','Regeneration_of = yes','Early_uptake_in = yes','Early_uptake_in = no','Changes_in_lym = oval','Changes_in_lym = round','Changes_in_lym = bean','Defect_in_node = lacunar','Defect_in_node = lac_central','Defect_in_node = lac_margin','Defect_in_node = no','Changes_in_node = lac_central','Changes_in_node = lacunar','Changes_in_node = no','Changes_in_node = lac_margin','Changes_in_stru = faint','Changes_in_stru = drop_like','Changes_in_stru = stripped','Changes_in_stru = coarse','Changes_in_stru = diluted','Changes_in_stru = grainy','Changes_in_stru = no','Changes_in_stru = reticular','Special_forms = vesicles','Special_forms = no','Special_forms = chalices','Dislocation_of = no','Dislocation_of = yes','Exclusion_of_no = yes','Exclusion_of_no = no',Lym_nodes_dimin,Lym_nodes_enlar,No_of_nodes_in,Outlier
1,0,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0.333333,0.285714,no
0,1,0,0,1,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0.333333,0.142857,no
There are 11 parsers available. But maybe it is my data, that is to large for the parser.
Thank you, this is a bug in the ELKI CSV parser.
It did not expect the class column to have a label.
So if your remove the ,Outlier part of your first line (or the first line completely), it should read this file just fine.
I will push a change that makes it more robust here (it will still lose the label though, because ELKI currently has support column labels for numerical columns but not for string label columns).

Simple way to convert a "string" into a [[string]]?

Is there a way to convert or create a new [[bracket style string]] based on an existing 'quote style string'?
s = "one\ntwo" -- how the string was created
s2 = [[one\ntwo]] -- what i want the new string to be
Escaping the escape sequence seems to achieve the desired effect, at least in this case.
s2 = string.gsub(s, "\n", "\\n")
> print(s2)
one\ntwo
One way is to make a table that has all the possible escape sequences:
local t = {["\a"] = [[\a]],
["\b"] = [[\b]],
["\f"] = [[\f]],
["\n"] = [[\n]],
["\r"] = [[\r]],
["\t"] = [[\t]],
["\r"] = [[\r]],
["\\"] = [[\\]],
["\""] = [["]],
["\'"] = [[']],
}
local s2 = s:gsub(".", t)

Rewrite variable in Erlang

I am playing with records and list. Please, I want to know how to use one variable twice. When I assign any values into variable _list and after that I try rewrite this variable then raising error:
** exception error: no match of right hand side value
-module(hello).
-author("anx00040").
-record(car, {evc, type, color}).
-record(person, {name, phone, addresa, rc}).
-record(driver, {rc, evc}).
-record(list, {cars = [], persons = [], drivers = []} ).
%% API
-export([helloIF/1, helloCase/1, helloResult/1, helloList/0, map/2, filter/2, helloListCaA/0, createCar/3, createPerson/4, createDriver/2, helloRecords/0, empty_list/0, any_data/0, del_Person/1, get_persons/1, do_it_hard/0, add_person/2]).
createCar(P_evc, P_type, P_color) -> _car = #car{evc = P_evc, type = P_type, color = P_color}, _car
.
createPerson(P_name, P_phone, P_addres, P_rc) -> _person= #person{name = P_name, phone = P_phone, addresa = P_addres, rc = P_rc}, _person
.
createDriver(P_evc, P_rc) -> _driver = #driver{rc = P_rc, evc = P_evc}, _driver
.
empty_list() ->
#list{}.
any_data() ->
_car1 = hello:createCar("BL 4", "Skoda octavia", "White"),
_person1 = hello:createPerson("Eduard B.","+421 917 111 711","Kr, 81107 Bratislava1", "8811235"),
_driver1 = hello:createDriver(_car1#car.evc, _person1#person.rc),
_car2 = hello:createCar("BL 111 HK", "BMW M1", "Red"),
_person2 = hello:createPerson("Lenka M","+421 917 111 111","Krizn0, 81107 Bratislava1", "8811167695"),
_driver2 = hello:createDriver(_car2#car.evc, _person2#person.rc),
_car3 = hello:createCar("BL 123 AB", "Audi A1 S", "Black"),
_person3 = hello:createPerson("Stela Ba.","+421 918 111 711","Azna 20, 81107 Bratislava1", "8811167695"),
_driver3 = hello:createDriver(_car3#car.evc, _person3#person.rc),
_list = #list{
cars = [_car1,_car2,_car3],
persons = [_person1, _person2, _person3],
drivers = [_driver1, _driver2, _driver3]},
_list.
add_person(List, Person) ->
List#list{persons = lists:append([Person], List#list.persons) }.
get_persons(#list{persons = P}) -> P.
do_it_hard()->
empty_list(),
_list = add_person(any_data(), #person{name = "Test",phone = "+421Test", addresa = "Testova 20 81101 Testovo", rc =88113545}),
io:fwrite("\n"),
get_persons(add_person(_list, #person{name = "Test2",phone = "+421Test2", addresa = "Testova 20 81101 Testovo2", rc =991135455}))
.
But it raising error when i use variable _list twice:
do_it_hard()->
empty_list(),
_list = add_person(any_data(), #person{name = "Test",phone = "+421Test", addresa = "Testova 20 81101 Testovo", rc =88113545}),
_list =add_person(_list, #person{name = "Test2",phone = "+421Test2", addresa = "Testova 20 81101 Testovo2", rc =991135455}),
get_persons(_list)
.
In the REPL, it can be convenient to experiment with things while re-using variable names. There, you can do f(A). to have Erlang "forget" the current assignment of A.
1> Result = connect("goooogle.com").
{error, "server not found"}
2> % oops! I misspelled the server name
2> f(Result).
ok
3> Result = connect("google.com").
{ok, <<"contents of the page">>}
Note that this is only a REPL convenience feature. You can't do this in actual code.
In actual code, variables can only be assigned once. In a procedural language (C, Java, Python, etc), the typical use-case for reassignment is loops:
for (int i = 0; i < max; i++) {
conn = connect(servers[i]);
reply = send_data(conn);
print(reply);
}
In the above, the variables i, conn, and reply are reassigned in each iteration of the loop.
Functional languages use recursion to perform their loops:
send_all(Max, Servers) ->
send_loop(1, Max, Servers).
send_loop(Current, Max, _Servers) when Current =:= Max->
ok;
send_loop(Current, Max, Servers) ->
Conn = connect(lists:nth(Current, Servers)),
Reply = send_data(Conn),
print(Reply).
This isn't very idiomatic Erlang; I'm trying to make it mirror the procedural code above.
As you can see, I'm getting the same effect, but my assignments within a function are fixed.
As a side note, you are using a lot of variable names beginning with underscore. In Erlang this is a way of hinting that you will not be using the value of these variables. (Like in the above example, when I've reached the end of my list, I don't care about the list of servers.) Using a leading underscore as in your code turns off some useful compiler warnings and will confuse any other developers who look at your code.
In some situations it is convenient to use use SeqBind:
SeqBind is a parse transformation that auto-numbers all occurrences of these bindings following the suffix # (creating L#0, L#1, Req#0, Req#1) and so on.
Simple example:
...
-compile({parse_transform,seqbind}).
...
List# = lists:seq(0, 100),
List# = lists:filter(fun (X) -> X rem 2 == 0 end, List#)
...
I used google...
Erlang is a single-assignment language. That is, once a variable has been given a value, it cannot be given a different value. In this sense it is like algebra rather than like most conventional programming languages.
http://www.cis.upenn.edu/~matuszek/General/ConciseGuides/concise-erlang.html

Coffeescript loop simplifying

Sended data is Ruby format:
mob = {id: 1, xpos:100, ypos:150, xposDest:150, yposDest:100, attacked:0}
WebsocketRails[:channel_name].trigger(:event_name, mob)
How could i make this loop simpler? (it's coffeescript)
get_all_mobs: (mob) -> // getting "mob" with Websockets
mob_list[mob.id].id = mob.id
mob_list[mob.id].xpos = mob.xpos if mob.xpos?
mob_list[mob.id].ypos = mob.ypos if mob.ypos?
mob_list[mob.id].xposDest = mob.xposDest if mob.xposDest?
mob_list[mob.id].yposDest = mob.yposDest if mob.yposDest?
mob_list[mob.id].health = mob.health if mob.health?
mob_list[mob.id].level = mob.level if mob.level?
mob_list[mob.id].max_health = mob.max_health if mob.max_health?
mob_list[mob.id].attacked = mob.attacked if mob.attacked?
mob_list[mob.id].steps = mob.steps if mob.steps?
Was tryed something like this, but its wrong:
get_all_mobs: (mob) -> // getting "mob" with Websockets
for attribute in mob
mob_list[mob.id].attribute = mob.attribute
This should do:
get_all_mobs: (mob) -> // getting "mob" with Websockets
for own key, value of mob
mob_list[mob.id][key] = value if value?

Resources