# Function "ds.dataFrameSubset" breaks when using DSLite

**URL:** <https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525>\
**Category:** Beginner Support\
**Created:** [16 March 2022 17:01 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525 "2022-03-16T17:01:20Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![manuhuth](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@manuhuth](https://datashield.discourse.group/u/manuhuth)\
**Post date:** [16 March 2022 17:01 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/1 "2022-03-16T17:01:20Z")

</div>

Dear community,

I recently started to work with Datashield and ran into trouble using the ds.dataFrameSubset function within the DSLite framework.

**Problem:** For me, the function ds.dataFrameSubset returns the error “cannot coerce class ‘“function”’ to a data.frame” on all servers, if I use DSLite. However, when I use the servers from the virtual machines, as in the tutorials, the function works perfectly fine.

**Reproduction of not working code**

```auto
library(DSLite)
library(dsBaseClient)

logindata.dslite.cnsim <- setupCNSIMTest()
connections <- datashield.login(logindata.dslite.cnsim, assign=T)
ds.dataFrameSubset(df.name = "D", V1.name = "D$GENDER", V2.name = "1",
                   Boolean.operator = "==", newobj = "CNSIM.subset.Males",
                   datasources= connections)

```

**Reproduction of working code** (from the tutorial)

```auto
library(DSI)
library(DSOpal)
library(dsBaseClient)

builder <- DSI::newDSLoginBuilder()
builder$append(server = "server1", url = "http://192.168.56.100:8080/",
               user = "administrator", password = "datashield_test&", driver = "OpalDriver")
builder$append(server = "server2", url = "http://192.168.56.101:8080/",
               user = "administrator", password = "datashield_test&", driver = "OpalDriver")

logindata <- builder$build()

connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D")

DSI::datashield.assign.table(conns = connections, symbol = "D", table = c("CNSIM.CNSIM1","CNSIM.CNSIM2", "CNSIM.CNSIM3"))
ds.dataFrameSubset(df.name = "D", V1.name = "D$GENDER", V2.name = "1",
                   Boolean.operator = "==", newobj = "CNSIM.subset.Males",
                   datasources= connections)

```

Has someone experienced similar problems or has an idea what is going on? (It could definitely be a beginners mistake! 🙂)

---

<div class="post-metadata">

**Author:** ![alexwesterberg](https://avatars.discourse-cdn.com/v4/letter/a/9fc29f/32.png) [@alexwesterberg](https://datashield.discourse.group/u/alexwesterberg)\
**Post date:** [18 March 2022 10:55 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/3 "2022-03-18T10:55:22Z")

</div>

Hia manuhuth, welcome to the forums!

Was there an error generated from the code that didn’t work? And if so, could you post it for us to read?

Thanks, Alex

---

<div class="post-metadata">

**Author:** ![manuhuth](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@manuhuth](https://datashield.discourse.group/u/manuhuth)\
**Post date:** [18 March 2022 11:55 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/4 "2022-03-18T11:55:54Z")

</div>

Hi Alex,

thanks for your reply! Sorry, the error message was a bit hidden in my initial post, I should have made it clearer. 🙂The generated error on all servers was: "_cannot coerce class ‘function’ to a data.frame_”

I have kept on working on the problem and found that the function call using ds.dataFrameSubset(df.name=“D”, …) could not find the object D (which is the name of the data frame symbol; see initial post) on the server side. Since D() is a pre-loaded function in the R environment, the server then used this D() function instead of the data frame and tried to make a data frame out of the function, explaining the error message.

If I change the symbol name in my whole script to something else, e.g. “D\_test”, the error message from all server sides is that the object “D\_test” cannot be found. However, when I run `datashield.symbols(connections)`, the output shows that “D\_test” is defined on all servers. Furthermore, all of the subsequent calls work (they work as well when the symbol is “D” instead of “D\_test”):

```auto
ds.dim(x = 'D_test') 
ds.colnames(x='D_test', datasources = connections)
ds.class(x='D_test$LAB_HDL', datasources = connections) 
ds.quantileMean(x='D_test$LAB_HDL', datasources = connections)
ds.mean(x='D_test$LAB_HDL', datasources = connections)

```

Trying to trace out the problem further, I found that the server side function that causes the error is “dataFrameSubsetDS1(…)”. The error occurs in [line 158](https://github.com/datashield/dsBase/blob/master/R/dataFrameSubsetDS1.R), when the function evaluates the string to build the data frame on the server side, which is then not found.

```auto
df2subset <- eval(parse(text=df.name.2)) #In my example df.name.2 is: paste0("data.frame(",D_test,")")

```

I was wondering why the other client side functions are able to find the object “D” or “D\_test” but “ds.dataFrameSubset” is not, and why this issue only occurs using DSLite.

Would you have an idea what could cause the described behavior? 🙂

Thanks, Manu

---

<div class="post-metadata">

**Author:** ![yannick](https://yyz2.discourse-cdn.com/free1/user_avatar/datashield.discourse.group/yannick/32/19_2.png) [@yannick](https://datashield.discourse.group/u/yannick)\
**Post date:** [18 March 2022 12:14 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/5 "2022-03-18T12:14:12Z")

</div>

I can reproduce it:

```auto
library(DSLite)
library(dsBaseClient)

logindata.dslite.cnsim <- setupCNSIMTest()

connections <- datashield.login(logindata.dslite.cnsim, assign=T, symbol = "D")
ds.dataFrameSubset(df.name = "D", V1.name = "D$GENDER", V2.name = "1",
                   Boolean.operator = "==", newobj = "CNSIM.subset.Males",
                   datasources= connections)
datashield.errors()
datashield.logout(connections)

```

The output is:

```auto
> ds.dataFrameSubset(df.name = "D", V1.name = "D$GENDER", V2.name = "1",
+ Boolean.operator = "==", newobj = "CNSIM.subset.Males",
+ datasources= connections)
  Aggregated (dataFrameSubsetDS1("D", "D$GENDER", "1", 1, NULL, NULL, FALSE)) [==========] 100% / 0s
Error: There are some DataSHIELD errors, list them with datashield.errors()
> datashield.errors()
$sim1
[1] "cannot coerce class ‘\"function\"’ to a data.frame"

$sim2
[1] "cannot coerce class ‘\"function\"’ to a data.frame"

$sim3
[1] "cannot coerce class ‘\"function\"’ to a data.frame"

```

Yannick

---

<div class="post-metadata">

**Author:** ![manuhuth](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@manuhuth](https://datashield.discourse.group/u/manuhuth)\
**Post date:** [18 March 2022 12:27 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/6 "2022-03-18T12:27:16Z")

</div>

Thanks to both of you! I have just written a post where I described my progress with the problem in more detail but it was deleted by the forum’s automatic spam filter. In short what I wrote:

The basic problem is that the function the function dataFrameSubsetDS1() does not find the object D on the server side. But there is a build-in R function D() which is then used instead causing the error [here](https://github.com/datashield/dsBase/blob/master/R/dataFrameSubsetDS1.R) in line 158, when calling:

```auto
df.name.2 <- paste0("data.frame(",df.name,")")
df2subset <- eval(parse(text=df.name.2)) 

```

However, `datashield.symbols(connections)` shows that “D” exists on the servers and other client side functions like `ds.dim(x = 'D') ` work.

Thanks, Manu

---

<div class="post-metadata">

**Author:** ![yannick](https://yyz2.discourse-cdn.com/free1/user_avatar/datashield.discourse.group/yannick/32/19_2.png) [@yannick](https://datashield.discourse.group/u/yannick)\
**Post date:** [18 March 2022 12:27 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/7 "2022-03-18T12:27:20Z")

</div>

It is because of the usage of the `eval()` in the `dataFrameSubsetDS1()` function which is not compliant with DSLite: `envir = parent.frame()` parameter is missing.

The same goes with `dataFrameSubsetDS2()`.

---

<div class="post-metadata">

**Author:** ![manuhuth](https://avatars.discourse-cdn.com/v4/letter/m/eb9ed0/32.png) [@manuhuth](https://datashield.discourse.group/u/manuhuth)\
**Post date:** [18 March 2022 12:37 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/8 "2022-03-18T12:37:52Z")

</div>

Thank you so much Yannick! It works, when I add `envir = parent.frame()` to the respective lines of eval(…) in `dataFrameSubsetDS1()` and `dataFrameSubsetDS2()` and install it locally. 👏

---

<div class="post-metadata">

**Author:** ![yannick](https://yyz2.discourse-cdn.com/free1/user_avatar/datashield.discourse.group/yannick/32/19_2.png) [@yannick](https://datashield.discourse.group/u/yannick)\
**Post date:** [18 March 2022 12:41 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/9 "2022-03-18T12:41:26Z")

</div>

When executed in a R server, the parent frame is the R session. In DSLite it is an environment that encapsulates the “server-side” operations. Specifying `envir = parent.frame()` makes the code more generic.

DSLite should be part of the test suite.

---

<div class="post-metadata">

**Author:** ![tombishop](https://yyz2.discourse-cdn.com/free1/user_avatar/datashield.discourse.group/tombishop/32/23_2.png) [@tombishop](https://datashield.discourse.group/u/tombishop)\
**Post date:** [18 March 2022 12:47 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/10 "2022-03-18T12:47:44Z")

</div>

Here is a related issue:

> <https://github.com/datashield/dsBaseClient/issues/389>
>
> The default \[symbol\](https://github.com/datashield/DSI/blob/7d12fbdaf639654287b3…3264a952ac66d43f831e/R/datashield.login.R#L142) name when assigning data in a new DataSHIELD session is "D".
> 
> If something goes wrong during assignment, the log in still occurs. Although the user gets an error they might not notice. They then try and do an operation like \`ds.asNumeric("D$cens", "CENS.num")\` but receive the error:
> 
> \`\`\`
> Error in D$cens : object of type 'closure' is not subsettable\\n"
> \`\`\`
> This causes confusion, and it happens because there is a function \`D()\`.
> 
> Perhaps we should consider a different default name? Definitely not T or F. Maybe R? or DS?
> 
> I appreciate this produces a lot of work in documentation where "D" is hardcoded in already, so we might not want to do it.

We should try to do away with using “D” as the default name because it is also a function name. This can result in cryptic error messages!!

---

<div class="post-metadata">

**Author:** ![yannick](https://yyz2.discourse-cdn.com/free1/user_avatar/datashield.discourse.group/yannick/32/19_2.png) [@yannick](https://datashield.discourse.group/u/yannick)\
**Post date:** [18 March 2022 13:17 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/11 "2022-03-18T13:17:53Z")

</div>

@manuhuth FYI this issue was fixed a while ago and will be available in the next dsBase version (6.2) which will be released soon.

---

<div class="post-metadata">

**Author:** ![alexwesterberg](https://avatars.discourse-cdn.com/v4/letter/a/9fc29f/32.png) [@alexwesterberg](https://datashield.discourse.group/u/alexwesterberg)\
**Post date:** [18 March 2022 16:32 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/12 "2022-03-18T16:32:04Z")

</div>

> [@manuhuth](#):
>
> Thanks to both of you! I have just written a post where I described my progress with the problem in more detail but it was deleted by the forum’s automatic spam filter. In short what I wrote:

Huh, I’m sorry this happened to you Manu, I’ve checked the admin’s inbox but unfortunately doesn’t look like there’s a way to reinstate it 😕. Anyway, I see Yannick has given a good response, hope all goes well from here!

---

<div class="post-metadata">

**Author:** ![swheater](https://yyz2.discourse-cdn.com/free1/user_avatar/datashield.discourse.group/swheater/32/182_2.png) [@swheater](https://datashield.discourse.group/u/swheater)\
**Post date:** [21 March 2022 10:57 UTC](https://datashield.discourse.group/t/function-ds-dataframesubset-breaks-when-using-dslite/525/13 "2022-03-21T10:57:29Z")

</div>

There is a development task of integration the new data set into DSLite which remains to be done. Once this is complete dsBaseClient can be tested with DSLite. This will allow us to find the remaining incompatibilities with DSLite.

Stuart
