Як побудувати графік усіх стовпців кадру даних у R


76

Кадр даних містить n стовпців, і я хотів би отримати n графіків, по одному графіку для кожного стовпця.

Я новачок і не вільно володію R, у будь-якому випадку я знайшов два рішення.

Перший працює, але він не друкує назви стовпця (а вони мені потрібні!):

data <- read.csv("sample.csv",header=T,sep=",")
for ( c in data ) plot( c, type="l" )

Другий працює краще, оскільки друкує назву стовпця:

data <- read.csv("sample.csv",header=T,sep=",")
for ( i in seq(1,length( data ),1) ) plot(data[,i],ylab=names(data[i]),type="l")

Чи є якісь кращі (з точки зору мови R) рішення?


2
У вашому другому другому прикладі я б ініціалізував цикл так, for(i in seq_along(dat))і я б також не називав свої дані data.
Gavin Simpson 02

3
Ви read.csvможете зменшити до, read.csv("sample.csv")оскільки для інших аргументів лише встановлюються значення за замовчуванням.
G. Grothendieck 02

Відповіді:


85

ggplot2Пакет займає трохи навчання, але результати виглядають дуже добре, ви отримаєте гарні легенди, а також багато інших функцій хороші, все без необхідності писати багато коду.

require(ggplot2)
require(reshape2)
df <- data.frame(time = 1:10,
                 a = cumsum(rnorm(10)),
                 b = cumsum(rnorm(10)),
                 c = cumsum(rnorm(10)))
df <- melt(df ,  id.vars = 'time', variable.name = 'series')

# plot on same grid, each series colored differently -- 
# good if the series have same scale
ggplot(df, aes(time,value)) + geom_line(aes(colour = series))

# or plot on different plots
ggplot(df, aes(time,value)) + geom_line() + facet_grid(series ~ .)

введіть тут опис зображення введіть тут опис зображення


Приємна відповідь, але чому ви насправді вимагаєте переробки?
eliasah

Дякую @VerenaHaunschmid Я зрозумів це згодом :-)
eliasah

44

Існує дуже простий спосіб побудувати всі стовпці з кадру даних за допомогою окремих панелей або однієї панелі:

plot.ts(data)

Що дає (де X1 - X4 - назви стовпців):

введіть тут опис зображення

Подивіться на? Plot.ts для всіх варіантів.

Якщо ви не хочете більше контролювати свою функцію побудови графіку і не використовувати цикл, ви також можете зробити щось на зразок:

par(mfcol = c(ncol(data), 1))
Map(function(x,y) plot(x, main =y), data, names(data))

Дякую, навіть якщо це пов'язано з часовими рядами, я думаю, це може допомогти мені зрозуміти мої дані. Мені подобається однокласний!
Алессандро Якопсон

7
Лише невеличка примітка: при додаванні 'plot.type = c ("single")' ваша серія наноситься на одну ділянку, а не на окремі поля: data <- data.frame(x=c(rnorm(10)),y=c(rnorm(10)),z=c(rnorm(10))) plot.ts(data,plot.type=c("single"),lty=1:3)
Geek On Acid

@GeekOnAcid +1, велике спасибі за натяк на "одиначку".
Алессандро Якопсон,

Якщо ви збираєтеся використовувати single, вам слід також додати: col=rainbow(ncol(my.data))або щось подібне, щоб лінії були читабельними.
яскрава зірка

13

Ви можете стрибати через обручі і перетворити своє рішення в lapply, sapplyабо applyвиклик. (Я бачу, @jonw показує один із способів зробити це.) Крім того, що у вас вже є цілком прийнятним кодом.

Якщо це всі часові ряди або подібні, то наступна може бути підходящою альтернативою, яка будує кожну серію на власній панелі в одній області побудови графіків. Ми використовуємо zooпакет, оскільки він справді дуже добре обробляє упорядковані дані.

require(zoo)
set.seed(1)
## example data
dat <- data.frame(X = cumsum(rnorm(100)), Y = cumsum(rnorm(100)),
                  Z = cumsum(rnorm(100)))
## convert to multivariate zoo object
datz <- zoo(dat)
## plot it
plot(datz)

Що дає: Приклад можливостей побудови зоопарку


11

Я здивований, що ніхто не згадав matplot. Це досить зручно, якщо вам не потрібно будувати кожен рядок в окремих осях. Лише одна команда:

matplot(y = data, type = 'l', lty = 1)

Використовуйте, ?matplotщоб переглянути всі варіанти.

Щоб додати легенду, ви можете встановити колірну палітру, а потім додати її:

mypalette = rainbow(ncol(data))
matplot(y = data, type = 'l', lty = 1, col = mypalette)
legend(legend = colnames(data), x = "topright", y = "topright", lty = 1, lwd = 2, col = mypalette)

Що є matlab.dark.palette, звідки воно?
Алессандро Якопсон

1
@AlessandroJacopson - це функція кольорової палітри, яку я зазвичай використовую. Це з hyperSpecупаковки. Але тут було б краще використовувати більш відому функцію, тому я змінив її на rainbow. Якщо ви не знаєте про функції палітри, подивіться ?rainbow. Вибачте за плутанину.
Рустам Гулієв

7

Використовуючи деякі поради, наведені вище (особливо подяку @daroczig за names(df)[i]форму), ця функція друкує гістограму для числових змінних та гістограму для змінних факторів. Хороший початок вивчення кадру даних:

par(mfrow=c(3,3),mar=c(2,1,1,1)) #my example has 9 columns

dfplot <- function(data.frame)
{
  df <- data.frame
  ln <- length(names(data.frame))
  for(i in 1:ln){
    mname <- substitute(df[,i])
      if(is.factor(df[,i])){
        plot(df[,i],main=names(df)[i])}
        else{hist(df[,i],main=names(df)[i])}
  }
}

З найкращими побажаннями, Мат.


4

З lattice:

library(lattice)

df <- data.frame(time = 1:10,
                 a = cumsum(rnorm(10)),
                 b = cumsum(rnorm(10)),
                 c = cumsum(rnorm(10)))

form <- as.formula(paste(paste(names(df)[- 1],  collapse = ' + '),  
                         'time',  sep = '~'))

xyplot(form,  data = df,  type = 'b',  outer = TRUE)

3

Ви можете вказати заголовок (а також заголовок осей через xlabта ylab) за допомогою mainопції. Наприклад:

plot(data[,i], main=names(data)[i])

І якщо ви хочете побудувати (і зберегти) кожну змінну в dataframe, ви повинні використовувати png, pdfабо будь-який інший графічний драйвер вам потрібно, і після цього питання в dev.off()команду. Наприклад:

data <- read.csv("sample.csv",header=T,sep=",")
for (i in 1:length(data)) {
    pdf(paste('fileprefix_', names(data)[i], '.pdf', sep='')
    plot(data[,i], ylab=names(data[i]), type="l")
    dev.off()
}

Або намалюйте всі графіки до одного зображення за допомогою mfrowпараметра par(). Наприклад: використовуйте par(mfrow=c(2,2)для включення наступних 4 графіків в одне і те ж "зображення".


3

У мене немає R на цьому комп’ютері, але тут є тріщина. Ви можете використовувати parдля відображення декількох графіків у вікні, або подібним чином, щоб запропонувати клік перед відображенням наступної сторінки.

plotfun <- function(col) 
  plot(data[ , col], ylab = names(data[col]), type = "l")
par(ask = TRUE)
sapply(seq(1, length(data), 1), plotfun)

2

На жаль, ggplot2 не пропонує способу зробити це (легко) без перетворення даних у довгий формат. Ви можете спробувати боротися з цим, але перетворення даних буде просто простіше. Тут усі методи, в тому числі meltз reshape2, gatherз tidyr і pivot_longerз tidyr: Переформатування data.frame з широкого в довгий формат

Ось простий приклад використання pivot_longer:

> df <- data.frame(time = 1:5, a = 1:5, b = 3:7)
> df
  time a b
1    1 1 3
2    2 2 4
3    3 3 5
4    4 4 6
5    5 5 7

> df_wide <- df %>% pivot_longer(c(a, b), names_to = "colname", values_to = "val")
> df_wide
# A tibble: 10 x 3
    time colname   val
   <int> <chr>   <int>
 1     1 a           1
 2     1 b           3
 3     2 a           2
 4     2 b           4
 5     3 a           3
 6     3 b           5
 7     4 a           4
 8     4 b           6
 9     5 a           5
10     5 b           7

Як бачите, pivot_longerвибрані імена стовпців поміщає у те, що вказано параметром names_to("ім'я за замовчуванням"), а довгі значення - у те, що вказано values_to(значення " за замовчуванням"). Якщо я добре з іменами за замовчуванням, я можу використовувати use df %>% pivot_longer(c("a", "b")).

Тепер ви можете побудувати графік як зазвичай, напр.

ggplot(df_wide, aes(x = time, y = val, color = colname)) + geom_line()

введіть тут опис зображення


Я хотів би додати require(tidyr)і require(ggplot2)в свою відповідь , щоб він став Minimal Робочого прикладом.
Алессандро Якопсон,

@AlessandroJacopson Я думав, що зрозумів, що це потрібно. У будь-якому випадку, чи корисний MWE, якщо код вкраплений з поясненнями?
qwr

Для мене це корисно, в усякому разі це справа смаку, дякую за вашу відповідь.
Алессандро Якопсон

1

Якщо імена стовпців у .csvфайлі файлу є невірними R-іменами:

data <- read.csv("sample.csv",sep=";",head=TRUE)
data2 <- read.csv("sample.csv",sep=";",head=FALSE,nrows=1)

for ( i in seq(1,length( data ),1) ) plot(data[,i],ylab=data2[1,i],type="l")

1
Оскільки ви використовуєте тільки перший рядок з data2, було б більш ефективним , щоб встановити nrows = 1в read.csv.
Рустам Гулієв

0

Це посилання мені дуже допомогло для тієї ж проблеми:

p = ggplot() + 
  geom_line(data = df_plot, aes(x = idx, y = col1), color = "blue") +
  geom_line(data = df_plot, aes(x = idx, y = col2), color = "red") 

print(p)

https://rpubs.com/euclid/343644

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.