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

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

cannot pass argument to which with pipeline in R

问题

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

# 例子
DT <- data.table(x = c("a", "b", "c"), 
                 y = c(1L, 2L, 3L), 
                 z = c(1.1, 2.1, 3.1))

# 使用嵌套结构按类别筛选
changeCols <- colnames(DT)[which(as.vector(DT[,lapply(.SD, class)]) == "character")]
changeCols

# 使用管道按类别筛选
DT[,lapply(.SD, class)] %>%
  as.vector(.) == "character" %>%
  which(.)
# 出现错误:argument to 'which' is not logical

# 简单地中断管道可以纠正错误
cols <- DT[,lapply(.SD, class)] %>% as.vector(.) == "character"
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

# example
DT &lt;- data.table(x = c(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;), 
                 y = c(1L, 2L, 3L), 
                 z = c(1.1, 2.1, 3.1))

# filter by class with nested structure
changeCols &lt;- colnames(DT)[which(as.vector(DT[,lapply(.SD, class)]) == &quot;character&quot;)]
changeCols

# filter by class with pipeline
DT[,lapply(.SD, class)] %&gt;%
  as.vector(.) == &quot;character&quot; %&gt;%
  which(.)
# Error in which(.) : argument to &#39;which&#39; is not logical

# simply break the pipeline corrects the error
cols &lt;- DT[,lapply(.SD, class)] %&gt;% as.vector(.) == &quot;character&quot;
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"

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

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

quote(
    DT[,lapply(.SD, class)] |>
    as.vector(x=_) == "character" |> 
    which(x=_)
)
##as.vector(x = DT[, lapply(.SD, class)]) == which(x = "character")

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

DT[, which(lapply(.SD, class) == "character")]
#x 
#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;:

DT[,lapply(.SD, class)] %&gt;%
  {as.vector(.) == &quot;character&quot;} %&gt;%
    which(.)
#x 
#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).

quote(
    DT[,lapply(.SD, class)] |&gt;
    as.vector(x=_) == &quot;character&quot; |&gt; 
    which(x=_)
)
##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:

DT[, which(lapply(.SD, class) == &quot;character&quot;)]
#x 
#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:

确定