#r #dataframe
#r #dataframe
Вопрос:
У меня есть список фреймов данных, и я хочу удалить все столбцы, которые имеют 4 и меньше. Поэтому я хочу сохранить только столбцы с суммами 5 или более. Мой тестовый пример приведен ниже.
Я использую этот код для удаления столбцов.
NEWTEST = NULL
for (a in 1:length(TEST)) {
NEWTEST = colSums(TEST[[a]])
index = which(NEWTEST > 4)
TEST[[a]] = TEST[[a]][,index]}
#Change all in dataframes again
for (a in 1:length(TEST)) {
TEST[[a]] = as.data.frame(TEST[[a]])}
Теперь проблема в том, что, когда остается только 1 столбец, как в df2 и df3, имя столбца исчезает. Но для меня это имя столбца очень важно, и мне нужно его сохранить (здесь я просто выбрал Vn, но на самом деле это описательное имя столбца и разное в каждом фрейме данных.
Есть идеи, как я могу просто сохранить это имя?
TEST = structure(list(df1 = structure(list(V1 = c(15L, 18L, 18L, 12L,
14L, 16L, 10L, 14L, 29L, 16L, 20L, 20L, 13L, 3L, 14L), V2 = c(0L,
1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 2L, 1L, 0L, 0L), V3 = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), V4 = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), V5 = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), V6 = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("V1",
"V2", "V3", "V4", "V5", "V6"), row.names = c(NA, 15L), class = "data.frame"),
df2 = structure(list(V1 = c(4L, 3L, 1L, 2L, 3L, 3L, 3L, 3L,
4L, 6L, 3L, 4L, 2L, 7L, 3L), V2 = c(0L, 0L, 0L, 0L, 0L, 0L,
1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), V3 = c(0L, 1L, 0L, 0L,
0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L), V4 = c(0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), V5 = c(0L,
0L, 0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
V6 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L)), .Names = c("V1", "V2", "V3", "V4", "V5",
"V6"), row.names = c(1L, 6L, 7L, 9L, 20L, 23L, 24L, 27L,
28L, 29L, 32L, 33L, 34L, 37L, 38L), class = "data.frame"),
df3 = structure(list(V1 = c(7L, 10L, 5L, 3L, 4L, 6L, 6L,
6L, 6L, 7L, 10L, 7L, 3L, 4L, 4L), V2 = c(0L, 0L, 0L, 0L,
0L, 1L, 2L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), V3 = c(0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L), V4 = c(0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L),
V5 = c(0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L), V6 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L)), .Names = c("V1", "V2", "V3",
"V4", "V5", "V6"), row.names = c(1L, 19L, 20L, 21L, 22L,
23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 38L, 39L), class = "data.frame")), .Names = c("df1",
"df2", "df3"))
Ответ №1:
Мы можем использовать lapply
для перебора list
, создания условия colSums
и использования его в качестве индекса столбца. Обратите внимание, что по умолчанию, если мы используем индекс или имя столбца без запятой, оно берется как индекс столбца / имя столбца в data.frame
lapply(TEST, function(x) x[colSums(x) >= 5])
Или с tidyverse
library(purrr)
library(dplyr)
map(TEST, ~ .x %>%
select(where(~ sum(.) >= 5)))
Причина поведения, возникающего при использовании OP, основана на drop = TRUE
in data.frame
, когда есть одна строка / столбец, т.Е. Он уменьшает свои размеры до возвращаемого вектора. В этом случае мы могли бы просто подмножество с индексом столбца без ,
или, если мы используем ,
, то обязательно укажите drop = FALSE
lapply(TEST, function(x) x[, colSums(x) >= 5, drop = FALSE])
Комментарии:
1. Спасибо, похоже, что имена сохраняются!