Достучаться до столбцов data.frame

Вопросы по статистическому пакету R. Не обязательно гео.
Ответить
KolesovDmitry
Гуру
Сообщения: 810
Зарегистрирован: 22 авг 2007, 14:58
Репутация: 123
Откуда: Казань

Достучаться до столбцов data.frame

Сообщение KolesovDmitry »

Создаю data.frame, например:

Код: Выделить всё

> snow = data.frame(year=c(1970:1979), cover=c(6.5,12, 14.9, 10, 10.7, 7.9, 21.9, 12.5, 14.5, 9.2))
теперь хочу построить гистограмму распределения параметра cover, получаю ошибку:

Код: Выделить всё

> hist(snow['cover'])
Ошибка в hist.default(snow["cover"]) : 'x' должен быть числовым
Смысл ошибки я понимаю и нахожу ее логичной, поскольку

Код: Выделить всё

> class(snow["cover"])
[1] "data.frame"
Но я теряюсь в догадках, как же тогда достучаться до отдельного столбца, чтобы его можно было скармливать функциям?
Аватара пользователя
Максим Дубинин
MindingMyOwnBusiness
Сообщения: 9129
Зарегистрирован: 06 окт 2003, 20:20
Репутация: 748
Ваше звание: NextGIS
Откуда: Москва
Контактная информация:

Re: Достучаться до столбцов data.frame

Сообщение Максим Дубинин »

столбцы адресуются либо через $, либо через предварительный attach

Код: Выделить всё

hist(snow$cover)
или

Код: Выделить всё

attach(snow)
hist(cover)
Я лично предпочитаю первый способ, как явно указывающий из какого фрейма идут данные.
пристегивайтесь, турбулентность прямо по курсу
gamm
Гуру
Сообщения: 4168
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1107
Ваше звание: программист
Откуда: Казань

Re: Достучаться до столбцов data.frame

Сообщение gamm »

Максим Дубинин писал(а):столбцы адресуются либо через $, либо через предварительный attach

Код: Выделить всё

hist(snow$cover)
или

Код: Выделить всё

attach(snow)
hist(cover)
Я лично предпочитаю первый способ, как явно указывающий из какого фрейма идут данные.
attach категорически не рекомендуется, имена из data.frame попадают в глобальный environment, и могут замаскировать системные имена и переменные. Это типичная ошибка, за которую бьют по рукам студентов 1-го курса (ее можно делать во всех языках).

Кстати, пример hist(my.data["my.column"]) не работает потому, что R не понимает, чего от него хотят. нужно так:
hist(my.data[,"my.column"]) и все наладится :D
ymr3R9Jge
Активный участник
Сообщения: 117
Зарегистрирован: 31 окт 2011, 00:18
Репутация: 14
Откуда: Кривий Ріг

Re: Достучаться до столбцов data.frame

Сообщение ymr3R9Jge »

А каким образом можно задать условие комплексной сортировки данных. Например у меня data.frame_1 размерностью N*N, столбцы которого являются численными, факторными и текстовыми данными. Я могу записать в новый объект data.frame_2 все эти данные с сортировкой только по одному столбцу, например по столбцу А (который 3-й по счёту) выбрать данные больше 20,5:

> data.frame_2 <- data.frame_1[data.frame_1[, 3] > 20,5,]

Но у меня никак не получается отсортировать и записать в новый объект данные одновременно по нескольким столбцам (например данные численного столбца А>20,5 и данные факторного столбца Б="Г"). :oops:
gamm
Гуру
Сообщения: 4168
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1107
Ваше звание: программист
Откуда: Казань

Re: Достучаться до столбцов data.frame

Сообщение gamm »

вы странно используете термины, никакой сортировки у вас нет, есть просто выборка. А для условий есть операции Булевой алгебры И, ИЛИ, НЕ - в документации все написано.

требуемая выборка выглядит так:
data.frame_2 <- data.frame_1[(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]=="Г" ),]
ymr3R9Jge
Активный участник
Сообщения: 117
Зарегистрирован: 31 окт 2011, 00:18
Репутация: 14
Откуда: Кривий Ріг

Re: Достучаться до столбцов data.frame

Сообщение ymr3R9Jge »

gamm писал(а):вы странно используете термины...
- я только начинающий инфо-геолог, и с информатикой-математикой немного туговато :oops:
gamm писал(а): в документации все написано
- в документации-то написано, но я перерыл кучу источников (как русско- так и англоязычных) и не имея опыта программирования нигде не нашёл сносного примера требуемого выражения...
СПАСИБО!!! Выражение работает! Но позволю себе задать ещё вопрос (опять-же из-за плохого знания информатики): мне нужно скопировать data.frame_1 в data.frame_2 и при этом отбраковать данные столбца А>20,5, если в факторном столбце Б они принадлежат к группе "Г" (т.е. отбросить из таблицы несколько выбросов для одной группы). Как это реализовать?
gamm
Гуру
Сообщения: 4168
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1107
Ваше звание: программист
Откуда: Казань

Re: Достучаться до столбцов data.frame

Сообщение gamm »

ymr3R9Jge писал(а):мне нужно скопировать data.frame_1 в data.frame_2 и при этом отбраковать данные столбца А>20,5, если в факторном столбце Б они принадлежат к группе "Г" (т.е. отбросить из таблицы несколько выбросов для одной группы). Как это реализовать?
это то же, что я уже написал, с минимальными изменениями ...

data.frame_2 <- data.frame_1[(data.frame_1[, 3] > 20.5)& !(data.frame_1[, 4]=="Г" ),]

или

data.frame_2 <- data.frame_1[(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]!="Г" ),]

P.S. Почитайте википедию про Булеву алгебру, исчисление высказываний, логические выражения и их связь с теорией множеств, и т.д., и запись логических операций в R, ничего сложного в этом нет. Та же арифметика, но с двумя значениями - ИСТИНА (TRUE) и ЛОЖЬ (FALSE). И учите английский, документации по R огромное количество ...
ymr3R9Jge
Активный участник
Сообщения: 117
Зарегистрирован: 31 окт 2011, 00:18
Репутация: 14
Откуда: Кривий Ріг

Re: Достучаться до столбцов data.frame

Сообщение ymr3R9Jge »

gamm писал(а): data.frame_2 <- data.frame_1[(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]!="Г" ),]
... не работает... :cry:
Выбираются значения больше 20.5 и одновременно отбрасываются все значения, принадлежащие группе "Г".
Наверное я не корректно поставил задачу. Мне нужно перебросить в новую таблицу все данные (включая и группу "Г"), выкинув лишь те значения группы "Г", которые превышают 20.5.
Аватара пользователя
Игорь Черниенко
Активный участник
Сообщения: 137
Зарегистрирован: 28 мар 2009, 01:05
Репутация: 11
Откуда: Хабаровск, Южно-Сахалинск

Re: Достучаться до столбцов data.frame

Сообщение Игорь Черниенко »

gamm, а почему результат вот этого выражения
data.frame_2 <- data.frame_1[-(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]=="Г" ),]
аналогичен этому?
data.frame_2 <- data.frame_1[(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]=="Г" ),]
Я не силен в буллевой алгебре, но когда в R перед условием ставят минус, соответствующие строки, вроде, должны исключаться.
ymr3R9Jge , нужный Вам результат, в принципе, можно получить вот так
ftr<-as.numeric(row.names(data.frame_1[(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]=="Г" ),]))
data.frame_2<-data.frame_1[-ftr,]
это как-то не через правильное место но ничего лучше пока не выходит :о)
gamm
Гуру
Сообщения: 4168
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1107
Ваше звание: программист
Откуда: Казань

Re: Достучаться до столбцов data.frame

Сообщение gamm »

Игорь Черниенко писал(а):gamm, а почему результат вот этого выражения
data.frame_2 <- data.frame_1[-(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]=="Г" ),]
аналогичен этому?
data.frame_2 <- data.frame_1[(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]=="Г" ),]
Я не силен в буллевой алгебре, но когда в R перед условием ставят минус, соответствующие строки, вроде, должны исключаться.
"Смешались в кучу кони , люди ..." :D

> foo<-c(TRUE,FALSE,TRUE)
> -foo
[1] -1 0 -1
> (-foo)&TRUE
[1] TRUE FALSE TRUE
> (-foo)|FALSE
[1] TRUE FALSE TRUE

исключаться строки будут, если в индексе используются номера строк. Если минус стоит перед логическим индексом (который TRUE/FALSE), то, в соотвествии с Традицией (С-шной), TRUE превращается в -1, а FALSE в 0. Ежели теперь этот вектор использовать в логическом выраженеии, то (в соответствии с С-шной традицией) нули превращаются в FALSE, все остальное в TRUE, т.е. минус какбэ не действует на логические индексы.

Так что ваш совет работать не будет, для исключения нужно использовать логическое НЕ (а не минус), логическое НЕ в R - восклицательный знак ("!"). Т.е. будет так:

ind<-(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]!="Г" ) # найти, чего не нужно, и положить в ind
data.frame_2 <- data.frame_1[!ind,] # копировать все, кроме ind

P.S. R, конечно, далеко до PL/1, но здесь тоже почти все почти во все преобразуется, иногда с весьма неожиданными результатами :D
ymr3R9Jge
Активный участник
Сообщения: 117
Зарегистрирован: 31 окт 2011, 00:18
Репутация: 14
Откуда: Кривий Ріг

Re: Достучаться до столбцов data.frame

Сообщение ymr3R9Jge »

gamm писал(а): ... Т.е. будет так:
ind<-(data.frame_1[, 3] > 20.5)&(data.frame_1[, 4]!="Г" ) # найти, чего не нужно, и положить в ind
data.frame_2 <- data.frame_1[!ind,] # копировать все, кроме ind
P.S. R, конечно, далеко до PL/1, но здесь тоже почти все почти во все преобразуется, иногда с весьма неожиданными результатами :D
Да, работает именно этот пример.
Спасибо ОГРОМНОЕ! Вы очень мне помогли. Теперь я умею напрямую работать с первичной таблицей данных (базой данных). До этого мне пришлось понаделать кучу таблиц с использованием SQL-запросов: сортировка по одной породе, сортировка по другой породе и т.д., а затем загрузить их в R. :lol:

P.S. А по поводу англоязычных источников - их-то много, но в основном все написаны по стандартной схеме и на стандартных примерах (наборах базовых данных). По-этому не владея основами программирования очень трудно разобраться в тонких но повседневных вопросах.
gamm
Гуру
Сообщения: 4168
Зарегистрирован: 15 окт 2010, 08:33
Репутация: 1107
Ваше звание: программист
Откуда: Казань

Re: Достучаться до столбцов data.frame

Сообщение gamm »

ymr3R9Jge писал(а): По-этому не владея основами программирования очень трудно разобраться в тонких но повседневных вопросах.
программирование нужно изучать (именно программирование, а не языки программирования) - это тренирует мозги.

И на последок, в R возможна полная эмуляция SQL: join => merge(); select ... group by => tapply(), aggregate(); select ... where ... => см.выше; union => rbind()/cbind(), sort by ... => ind<-order(); p[ind,], etc. Не говоря о том, что R позволяет просто коннектиться к СУБД (либо через odbc, либо напрямую), и писать запросы для выборки..
Ответить

Вернуться в «R»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя