R: Создайте новый столбец с несколькими категориями (уровнями) на основе критерия двух других столбцов

мои данные выглядят следующим образом

> head(CPUE)
 Lon.rect Lat.rect q1 q4
 1 13.5 54.25 0.1930234 1.76096260
 2 13.5 54.75 11.6866331 19.06265440
 3 13.5 55.25 24.2532215 33.64530930
 4 13.5 55.75 0.2113688 0.05731537
 5 14.5 54.25 2.5600818 8.72482876
 6 14.5 54.75 85.8657297 34.08524869

Теперь я хотел бы создать новый столбец с несколькими категориями (уровнями) на основе комбинации данных из подмножеств "Lon.rect" и "Lat.rect". Я хотел бы назвать категории чем-то другим, исходя из данных, содержащихся в каждом столбце. например, для Lon.rect = 13.5, Lat.rect = 54.25, имя категории в новом столбце будет "1A", а во второй строке категория будет "1B", поскольку Lat.rect содержит разные данные. Строка 5 будет "2A" и так далее.

"Lon.rect" и "Lat.rect" содержат координаты (если это имеет значение для всех) и имеют еще несколько комбинаций. От лота 13,5 до 22,5 и лат 54,25 до 58,75.

Я создал новый столбец под названием "subdiv":

CPUE["subdiv"] <- NA

Теперь весь массив данных выглядит следующим образом:

> head(CPUE)
 Lon.rect Lat.rect q1 q4 subdiv
 1 13.5 54.25 0.1930234 1.76096260 NA
 2 13.5 54.75 11.6866331 19.06265440 NA
 3 13.5 55.25 24.2532215 33.64530930 NA
 4 13.5 55.75 0.2113688 0.05731537 NA
 5 14.5 54.25 2.5600818 8.72482876 NA
 6 14.5 54.75 85.8657297 34.08524869 NA

Я знаю, что могу вводить все, как показано ниже, но это займет много времени и с тех пор много данных.

CPUE$subdiv[CPUE$Lon.rect>=13 & CPUE$Lon.rect<=14 & CPUE$Lat.rect>=54.0 & CPUE$Lat.rect<=54.5] <- "1A"
CPUE$subdiv[CPUE$Lon.rect>=13 & CPUE$Lon.rect<=14 & CPUE$Lat.rect>=54.5 & CPUE$Lat.rect<=55.0] <- "1B"
CPUE$subdiv[CPUE$Lon.rect>=13 & CPUE$Lon.rect<=14 & CPUE$Lat.rect>=55.0 & CPUE$Lat.rect<=55.5] <- "1C"

Надеюсь, я сделал свое описание совершенно ясным, иначе не стесняйтесь обращаться ко мне! Если у кого-то есть хорошее решение для любого из шагов, напишите обратно! Благодарю! /Filip

РЕДАКТИРОВАТЬ:

Дополнительная информация о моей проблеме

Имена столбцов выше; "1A", "1B" и "2A" - это просто примеры, чтобы понять, как я хочу, чтобы отношения были столбцами источника, я действительно хочу называть их чем-то другим, однако я получил небольшую помощь ниже, если кто-то заинтересован этого.

В моем случае я хотел бы назвать столбец Lat.rect после целых чисел, начиная с 37. Lon.rect будет немного сложнее. Это имя состоит из одной буквы и одного номера, начиная с G3 (в данном случае). Наибольшее число для каждой буквы будет равно 9, а затем следующая буква начинается с 0, поэтому следующее имя после G9 будет H0.

Если это поможет, мне не нужен скрипт для создания этой комбинации для всего алфавита. Минимальная возможная комбинация (из всех моих наборов данных, которые не нужны в настоящее время) - F9 и максимум H9.

Я также хотел бы, чтобы имя латинского языка было первым, а второе - вторым. Если было бы проще сначала поменять местоположение столбца в data.frame, чтобы затем создать имя, это было бы хорошо.

Готовой комбинацией первого ряда будет "37G3", а затем второй ряд "38G3". Строка 5 будет "37G4".

Если кто-то сможет мне помочь с этой второй частью, я был бы признателен!

2 ответа

В более общем плане, если ваши данные не отсортированы как это (по lon а затем по lat), и вы хотите, чтобы subdiv включал все levels lot и lan, вы могли бы:

CPUE <- data.frame(lon = as.vector(replicate(4, sample(13.5:22.5, 10, T))),
 lat = as.vector(replicate(4, sample(seq(54, 56.25, 0.25), 10, T))))

 num <- findInterval(CPUE$lon, sort(unique(CPUE$lon)))
 lett <- findInterval(CPUE$lat, sort(unique(CPUE$lat)))

 CPUE$subdiv <- paste(num, LETTERS[lett], sep = "")

 CPUE
 lon lat subdiv
 1 13.5 54.50 1C #this is the first possible "lon" and the third possible "lat"
 2 15.5 54.50 3C
 3 20.5 55.25 8F #this is the eigth possible "lon" and the sixth possible "lat"
 4 19.5 54.00 7A
 5 16.5 55.75 4H

ПРИМЕЧАНИЕ. Этот подход не будет работать, если (1) вы не хотите включать все возможные уровни "lon" и "lat", и (2) ваши данные не сортируются как отправленные.

РЕДАКТИРОВАТЬ

Может быть, что-то вроде этого?:

CPUE <- data.frame(lon = sort(rep(13.5:22.5, 13)),
 lat = rep(seq(54.25, 60.25, 0.5), 10))

 lat_names <- findInterval(CPUE$lat, sort(unique(CPUE$lat))) + 36

 lon_names <- as.vector(sapply(LETTERS, paste, 0:9, sep = ""))
 lon_names <- lon_names[match("G3", lon_names):length(lon_names)]
 lon_names <- lon_names[findInterval(CPUE$lon, sort(unique(CPUE$lon)))]

 CPUE$subdiv <- paste(lat_names, lon_names, sep = "")

 > CPUE
 lon lat subdiv
 1 13.5 54.25 37G3
 2 13.5 54.75 38G3
 3 13.5 55.25 39G3
 4 13.5 55.75 40G3
 5 13.5 56.25 41G3
 6 13.5 56.75 42G3
 7 13.5 57.25 43G3
 8 13.5 57.75 44G3
 9 13.5 58.25 45G3
 10 13.5 58.75 46G3
 11 13.5 59.25 47G3
 12 13.5 59.75 48G3
 13 13.5 60.25 49G3
 14 14.5 54.25 37G4
 15 14.5 54.75 38G4
 16 14.5 55.25 39G4
 17 14.5 55.75 40G4
 18 14.5 56.25 41G4
 19 14.5 56.75 42G4
 20 14.5 57.25 43G4
 ....


Использование interaction было бы одним из способов получить levels от unique комбинаций factors в ваших столбцах. Однако я использую match в первых двух столбцах, нахожу положение каждого элемента в table unique элементов. Затем я могу paste эти значения вместе и использовать as.factor принуждать к factor переменной. Я нахожу, что переименование уровней более интуитивно понятное для меня, и оно также не зависит от сортировки data.frame...

a <- match( df[,1] , unique( df[,1] ) )
b <- letters[ match( df[,2] , unique( df[,2] ) ) ]

df$new <- as.factor( paste0( a , b ) )
# Lon.rect Lat.rect q1 q4 new
#1 13.5 54.25 0.1930234 1.76096260 1a
#2 13.5 54.75 11.6866331 19.06265440 1b
#3 13.5 55.25 24.2532215 33.64530930 1c
#4 13.5 55.75 0.2113688 0.05731537 1d
#5 14.5 54.25 2.5600818 8.72482876 2a
#6 14.5 54.75 85.8657297 34.08524869 2b

licensed under cc by-sa 3.0 with attribution.