У меня есть таблица, которая выглядит так:
Name Grade Test1 Test2 Test3
Tim A 0.7 0.0 0.8
Amy B 0.8 0.0 0.5
John B 0.6 0.0 0.6
Я хочу получить список всех имен столбцов с числовым значением больше 0:
Test1 # Total would be 2.1
Test3 # Total would be 1.9
# Name and grade ignored as they are not numeric
# Test2 ignored because value is 0
Как это могло быть достигнуто в R?





library(dplyr)
df %>%
select(where(is.numeric)) |>
map_dbl(sum) |>
as_tibble(rownames = "Test") |>
filter(value > 0.0)
# A tibble: 2 × 2
Test value
<chr> <dbl>
1 Test1 2.1
2 Test3 1.9
Спасибо за подсказку, я отредактировал свой пост соответственно.
Вот tidyverse решение:
library(dplyr)
library(tidyr)
df %>%
mutate(across(Test1:Test3, ~case_when(. > 0 ~ cur_column()), .names = 'new_{col}')) %>%
unite(New_Col, starts_with('new'), na.rm = TRUE, sep = ' ') %>%
distinct(New_Col) %>%
pull(New_Col)
[1] "Test1 Test3"
Вот базовое решение R.
i <- sapply(df1, is.numeric)
names(df1)[i][colSums(df1[i]) > 0]
#> [1] "Test1" "Test3"
Created on 2023-07-09 with reprex v2.0.2
df1 <- "Name Grade Test1 Test2 Test3
Tim A 0.7 0.0 0.8
Amy B 0.8 0.0 0.5
John B 0.6 0.0 0.6"
df1 <- read.table(text = df1, header = TRUE)
Created on 2023-07-09 with reprex v2.0.2
Это мой ответ с dplyr функцией summarize_if, которая помогает суммировать только числовые столбцы.
text <-
"
Name Grade Test1 Test2 Test3
Tim A 0.7 0.0 0.8
Amy B 0.8 0.0 0.5
John B 0.6 0.0 0.6
"
df <- read.csv(text = text, sep = " ", header = TRUE)
library(dplyr)
df %>%
summarize_if (is.numeric, sum) %>%
.[, .[1,] > 0]
А если просто:
library(tidyverse)
colnames(select(df1, where(\(x) is.numeric(x) && sum(x) > 0 )))
#[1] "Test1" "Test3"
Мы просто выбираем столбец, если он одновременно является числовым и его сумма столбцов больше нуля. Обратите внимание, что вам нужно && вместо &, чтобы не пытаться вычислить сумму нечислового столбца.
Подобно @Rui Barradas, вот два других базовых варианта R
> names(df)[sapply(df, \(x) is.numeric(x) && any(x > 0))]
[1] "Test1" "Test3"
> names(which(sapply(df, \(x) is.numeric(x) && any(x > 0))))
[1] "Test1" "Test3"
Обратите внимание, что
select_ifзаменена другими функциями. наверное лучше сделатьselect(where(is.numeric))