获取子集函数中的变量值 – R

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

Get variable value in subset function - R

问题

在尝试获取子集函数中变量值时,我发现了一个问题。当运行代码时,我收到以下消息:“警告:Error in -: 无效的一元运算符参数”,因为子集函数“-c(val)”中的“val”未在上面定义为变量。

cname <- c("A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",
           "A11","A12","A13","A14","A15","A16","A17","A18","A19","A20",
           "A21","A22","A23","A24","A25","A26","A27","A28","A29","A30","A31")
    
for (i in 15:length(cname)) {
    val <- cname[i]
    ifelse(sum(!is.na(df2$val))==0, 
           df2 <- subset(df2, select = -c(val)), 
           df2)
}

df2 的结果是 此数据

我的期望结果是删除仅包含 NA 值的不必要列,如您可以在 这里 看到的那样。

如何获取 val 的值,以便删除仅包含 NA 值的列?


<details>
<summary>英文:</summary>

I found an issue while trying to get the value of a variable in the subset function. When I run the code, I receive the message: &quot;Warning: Error in -: invalid argument to unary operator&quot; because &quot;val&quot; in subset function &quot;-c(val)&quot; not define as variable above.


cname <- c("A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",
"A11","A12","A13","A14","A15","A16","A17","A18","A19","A20",
"A21","A22","A23","A24","A25","A26","A27","A28","A29","A30","A31")

for (i in 15:length(cname)) {
val <- cname[i]
ifelse(sum(!is.na(df2$val))==0,
df2 <- subset(df2, select = -c(val)),
df2)
}


The df2 results in [this data][1].

My expected result is to remove unnecessary columns that have NA values only, as you can see [here][2].


How can I get the value from val, so I can remove the columns that have only NA values?


  [1]: https://i.stack.imgur.com/xOpmt.png
  [2]: https://i.stack.imgur.com/8pCkf.png

</details>


# 答案1
**得分**: 0

We can use `subset` without a loop - use the vectorized `colSums` on a logical matrix (`is.na(df2)`) to return the count of NAs in each column, compare (`!=`) it with the number of rows (`nrow(df2)`) to create a logical vector, subset the column names, use that in `select` argument in `subset`:

```R
subset(df2, select = names(df2)[colSums(is.na(df2)) != nrow(df2)])

-output:

 A1 A2 A4 A5
1  1  1 NA 10
2  2  2 NA 10
3  3  3 NA 10
4  4 NA  3 10
5  5  5  2 10

Or with tidyverse - use select and check for any non-NA elements in each column for selecting the column:

library(dplyr)
df2 %>%
   select(where(~ any(!is.na(.x)))

-output:

  A1 A2 A4 A5
1  1  1 NA 10
2  2  2 NA 10
3  3  3 NA 10
4  4 NA  3 10
5  5  5  2 10

data

df2 <- data.frame(A1 = 1:5, A2 = c(1:3, NA, 5), A3 = NA_integer_,
     A4 = c(NA, NA, NA, 3, 2), A5 = 10)
英文:

We can use subset without a loop - use the vectorized colSums on a logical matrix (is.na(df2)) to return the count of NAs in each column, compare (!=) it with the number of rows (nrow(df2)) to create a logical vector, subset the column names, use that in select argument in subset

subset(df2, select = names(df2)[colSums(is.na(df2)) != nrow(df2)])

-output

 A1 A2 A4 A5
1  1  1 NA 10
2  2  2 NA 10
3  3  3 NA 10
4  4 NA  3 10
5  5  5  2 10

Or with tidyverse - use select and check for any non-NA elements in each column for selecting the column

library(dplyr)
df2 %&gt;%
   select(where(~ any(!is.na(.x))))

-output

  A1 A2 A4 A5
1  1  1 NA 10
2  2  2 NA 10
3  3  3 NA 10
4  4 NA  3 10
5  5  5  2 10

data

df2 &lt;- data.frame(A1 = 1:5, A2 = c(1:3, NA, 5), A3 = NA_integer_,
     A4 = c(NA, NA, NA, 3, 2), A5 = 10)

</details>



huangapple
  • 本文由 发表于 2023年4月4日 09:08:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/75924775.html
匿名

发表评论

匿名网友

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

确定