Есть ли функция R для создания подмножества по части имени столбца? - PullRequest
0 голосов
/ 30 декабря 2018

Я ищу функцию для разделения фрейма данных на несколько фреймов в конце имен столбцов.Для примера:

Year | hour | LOT | S123_AA | S135_AA | S1763_BB | S173_BB | ...

Итак, я хочу разбить его на 2 кадра данных:

Year | hour | LOT | S123_AA | S135_AA |

и

Year | hour | LOT | S1763_BB | S173_BB |

Мой ключевой момент заключается в сохранениипервые 3 столбца и добавьте все столбцы, где конечные имена _AA и _BB.

Спасибо за ваше время

Ответы [ 5 ]

0 голосов
/ 30 декабря 2018

Используйте ! и grepl() для фильтрации столбцов.

  • NOT BB означает, что AA и столбцы 1 ~ 3 будут сохранены
  • NOT AA означает BB и столбцы 1~ 3 будет сохранено

A <- ! grepl("BB", names(df))
B <- ! grepl("AA", names(df))

df[, A]
#   Year hour LOT S123_AA S135_AA
# 1    1    8  15      22      29
# 2    2    9  16      23      30
# 3    3   10  17      24      31

df[, B]
#   Year hour LOT S1763_BB S173_BB
# 1    1    8  15       36      43
# 2    2    9  16       37      44
# 3    3   10  17       38      45
0 голосов
/ 30 декабря 2018

Если у вас есть группа групп (как предполагает ... в вашем вопросе), вы можете использовать lapply, чтобы не указывать регулярное выражение для каждой группы:

# Sample data
df <- data.frame(
  Year = rnorm(3), 
  hour = rnorm(3), 
  LOT = rnorm(3), 
  S123_AA = rnorm(3), 
  S135_AA = rnorm(3), 
  S1763_BB = rnorm(3), 
  S173_BB = rnorm(3)
)

# Our groups
groups <- unique(gsub(".*_", "", names(df[grep("_", colnames(df))])))
groups
#> [1] "AA" "BB"

# Our group regex's
groupx <- paste0("_", groups, "$")
groupx
#> [1] "_AA$" "_BB$"

lapply(groupx, function(x) df[, c(1:3, grep(x, colnames(df)))])
#> [[1]]
#>          Year       hour       LOT   S123_AA     S135_AA
#> 1  0.07940092 -1.2628189  1.629389 -1.376438 -0.94292025
#> 2 -2.04122298  0.7471061  0.291170 -2.126642  0.24355149
#> 3  0.11448519  0.1710263 -0.736140 -1.087515 -0.07720119
#> 
#> [[2]]
#>          Year       hour       LOT   S1763_BB    S173_BB
#> 1  0.07940092 -1.2628189  1.629389 -0.3593335 0.64176748
#> 2 -2.04122298  0.7471061  0.291170  1.7928938 0.36021859
#> 3  0.11448519  0.1710263 -0.736140 -0.7853338 0.01439278

Создано в 2018-12-31 пакетом Представ (v0.2.1)

0 голосов
/ 30 декабря 2018

Вот основной ответ, ваш вариант использования может потребовать более сложных регулярных выражений внутри вызова grepl(), но это должно привести вас на правильный путь:

#make some sample data
x <- data.frame(Year = rnorm(3), hour = rnorm(3), LOT =  rnorm(3),S123_AA =  rnorm(3),S135_AA =  rnorm(3),S1763_BB =   rnorm(3),S173_BB =  rnorm(3))

#list the common columns
common_cols <- c("Year", "hour", "LOT")
#use grepl() to subset the columns that contain AA or BB
aa_cols <- names(x)[grepl("AA", names(x))]
bb_cols <- names(x)[grepl("BB", names(x))]

#create two new data frames
x_a <- x[, c(common_cols, aa_cols)]
x_b <- x[, c(common_cols, bb_cols)]
0 голосов
/ 30 декабря 2018

Одним из способов является исключение столбцов, которые вы делаете не хотите.

i <- grep("_AA$", names(df1))
j <- grep("_BB$", names(df1))

dfA <- df1[, -j]    # Exclude the 'BB' columns
dfB <- df1[, -i]    # Exclude the 'AA' columns

Используя тот же принцип исключения, но с tidyverse.

library(tidyverse)

df1 %>%
  select(names(.)[!grepl("_BB$", names(.))])

df1 %>%
  select(names(.)[!grepl("_AA$", names(.))])

Это может стать более tidyverse способом с предложением комментария пользователя NColl .

df1 %>% select(-ends_with('_BB'))

df1 %>% select(-ends_with('_AA'))

Данные.

df1 <- as.data.frame(matrix(1:49, ncol = 7))
nms <- scan(what = character(), sep = "|",
            text = "Year | hour | LOT | S123_AA | S135_AA | S1763_BB | S173_BB ")
names(df1) <- trimws(nms)
0 голосов
/ 30 декабря 2018

Вы можете просто выбрать правильный набор, используя grep.

df_AA = df[,c(1:3, grep("_AA$", colnames(df)))]
df_BB = df[,c(1:3, grep("_BB$", colnames(df)))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...