无法在R中使用管道将参数传递给”which”。

huangapple go评论107阅读模式
英文:

cannot pass argument to which with pipeline in R

问题

我想根据它们的属性筛选数据表的列。答案实际上基于Nera在这里的回答 https://stackoverflow.com/questions/7813578/convert-column-classes-in-data-table

  1. # 例子
  2. DT <- data.table(x = c("a", "b", "c"),
  3. y = c(1L, 2L, 3L),
  4. z = c(1.1, 2.1, 3.1))
  5. # 使用嵌套结构按类别筛选
  6. changeCols <- colnames(DT)[which(as.vector(DT[,lapply(.SD, class)]) == "character")]
  7. changeCols
  8. # 使用管道按类别筛选
  9. DT[,lapply(.SD, class)] %>%
  10. as.vector(.) == "character" %>%
  11. which(.)
  12. # 出现错误:argument to 'which' is not logical
  13. # 简单地中断管道可以纠正错误
  14. cols <- DT[,lapply(.SD, class)] %>% as.vector(.) == "character"
  15. which(cols)

我不明白为什么在使用管道时会出现错误,而在中断管道时错误被解决。谢谢!

英文:

I want to filter columns of a data.table based on their attribute. The answer is actually based on Nera's answer here https://stackoverflow.com/questions/7813578/convert-column-classes-in-data-table

  1. # example
  2. DT &lt;- data.table(x = c(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;),
  3. y = c(1L, 2L, 3L),
  4. z = c(1.1, 2.1, 3.1))
  5. # filter by class with nested structure
  6. changeCols &lt;- colnames(DT)[which(as.vector(DT[,lapply(.SD, class)]) == &quot;character&quot;)]
  7. changeCols
  8. # filter by class with pipeline
  9. DT[,lapply(.SD, class)] %&gt;%
  10. as.vector(.) == &quot;character&quot; %&gt;%
  11. which(.)
  12. # Error in which(.) : argument to &#39;which&#39; is not logical
  13. # simply break the pipeline corrects the error
  14. cols &lt;- DT[,lapply(.SD, class)] %&gt;% as.vector(.) == &quot;character&quot;
  15. which(cols)

I don't understand why there's an error when I use pipeline while the error was solved when breaking the pipe. Thanks!

答案1

得分: 2

你需要封装 as.vector(.) == "character" 这一部分,否则我认为被传递的只是字符串 "character"

  1. DT[, lapply(.SD, class)] %>%
  2. {as.vector(.) == "character"} %>%
  3. which(.)
  4. #x
  5. #1

在这种情况下,如果你将 %>% 替换为基本的 |>,将 . 替换为 _,然后使用 quote() 对其进行引用,你可以看到问题出在哪里(尽管基本管道不完全等同于 %>%,但这次用于调试问题非常有用):

  1. quote(
  2. DT[,lapply(.SD, class)] |>
  3. as.vector(x=_) == "character" |>
  4. which(x=_)
  5. )
  6. ##as.vector(x = DT[, lapply(.SD, class)]) == which(x = "character")

你也可以通过在 DT[i, j, by]data.table j 参数内工作来避免这个问题:

  1. DT[, which(lapply(.SD, class) == "character")]
  2. #x
  3. #1
英文:

You need to encapsulate the as.vector(.) == &quot;character&quot; bit, otherwise I think what is being piped forwards is just the string &quot;character&quot;:

  1. DT[,lapply(.SD, class)] %&gt;%
  2. {as.vector(.) == &quot;character&quot;} %&gt;%
  3. which(.)
  4. #x
  5. #1

On this occasion, you can see where it went wrong if you switch out the %&gt;% for the base |&gt;, . for _ and then quote() it (though the base pipe isn't identical to %&gt;% it was useful to debug the issue this time).

  1. quote(
  2. DT[,lapply(.SD, class)] |&gt;
  3. as.vector(x=_) == &quot;character&quot; |&gt;
  4. which(x=_)
  5. )
  6. ##as.vector(x = DT[, lapply(.SD, class)]) == which(x = &quot;character&quot;)

You could also avoid this by just working inside the data.table j argument of DT[i, j, by] like:

  1. DT[, which(lapply(.SD, class) == &quot;character&quot;)]
  2. #x
  3. #1

huangapple
  • 本文由 发表于 2023年6月16日 06:56:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76485977.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定