Скажите, что у меня есть эти данные:
library(dplyr)
data <- data.frame(num=c(1:6), val=c('1998-99', '1999-00', '2000-01', '2001-02', '2002-03', '2003-04'))
Затем у меня есть несколько вещей, которые было бы полезно выяснить, в основном о том, как значения в цикле относятся к другим значениям и как автоматизировать этот процесс.
Лучше всего было бы поставить это в цикле. Как это сделать с именами фреймов данных? Другими словами, как обращаться к имени data.frame в цикле?
data03 <- filter(data, num<=1)
data04 <- filter(data, num<=2)
data05 <- filter(data, num<=3)
data06 <- filter(data, num<=4)
data07 <- filter(data, num<=5)
data08 <- filter(data, num<=6)
Тогда как заставить этот цикл работать и упростить?
for (i in c(03, 04, 05, 06, 07, 08)) {
#I want to print the number corresponding to i
if (i= = "03") print(1)
if (i= = "04") print(2)
if (i= = "05") print(3)
if (i= = "06") print(4)
if (i= = "07") print(5)
if (i= = "08") print(6)
#I want to get the value corresponding to i for the plot title
if (i= = "03") title = "1998-99"
if (i= = "04") title = "1999-00"
if (i= = "05") title = "2000-01"
if (i= = "06") title = "2001-02"
if (i= = "07") title = "2002-03"
if (i= = "08") title = "2003-04"
#I want to open the data frame, data+i
df <- paste(data,i)
#I want to plot, using the title saved above
plot(df$num, main=title)
}
Я хочу сделать шесть графиков, по одному для каждого фрейма данных. Каждый сюжет должен иметь название, соответствующее году. Например, график для фрейма данных data03 должен иметь заголовок 1998-99. Я хочу, чтобы индекс цикла каким-то образом легко ссылался как на data.frame, так и на название года.
@ bill999 Мое обновление завершено. Пожалуйста, смотрите мой ответ. В этом случае нет необходимости использовать цикл for.
Итак, если я понимаю вашу проблему, вы спрашиваете, как вы можете ссылаться на элементы data.frame, не ссылаясь на их имена.
В этом случае, если у вас есть data.frame test.df
, мы можем использовать [[]]
для доступа к ним, как это
test.df <- data.frame(first=rnorm(10),second=rnorm(10))
test.df$first
[1] 0.8447835 -0.7210152 -1.6379253 -1.5695393 -1.2467788 -1.9273583 0.5633265 -0.4186060 1.3478030 -0.4379999
test.df[[1]]
[1] 0.8447835 -0.7210152 -1.6379253 -1.5695393 -1.2467788 -1.9273583 0.5633265 -0.4186060 1.3478030 -0.4379999
test.df$first == test.df[[1]]
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
Затем вы можете делать такие вещи, как использовать этот индекс для зацикливания.
Говоря более конкретно о ваших данных, если все, что вам нужно, это напечатать число с заголовком в val, вы можете просто сделать это.
for(i in 1:length(data$num){
plot(data$num[[i]],main=paste(data$val[[i]])
Вам не нужен цикл for. Вы можете использовать lapply
вывод в виде списка, и вы можете использовать lapply
для последующего анализа.
lapply(1:6, function(x) data %>% filter(num <= x))
# [[1]]
# num val
# 1 1 1998-99
#
# [[2]]
# num val
# 1 1 1998-99
# 2 2 1999-00
#
# [[3]]
# num val
# 1 1 1998-99
# 2 2 1999-00
# 3 3 2000-01
#
# [[4]]
# num val
# 1 1 1998-99
# 2 2 1999-00
# 3 3 2000-01
# 4 4 2001-02
#
# [[5]]
# num val
# 1 1 1998-99
# 2 2 1999-00
# 3 3 2000-01
# 4 4 2001-02
# 5 5 2002-03
#
# [[6]]
# num val
# 1 1 1998-99
# 2 2 1999-00
# 3 3 2000-01
# 4 4 2001-02
# 5 5 2002-03
# 6 6 2003-04
А вот полный код для фильтрации фрейма данных и последующего создания графиков.
dat <- lapply(1:6, function(x) data %>% filter(num <= x))
lapply(dat, function(x){
plot(x$num, main = x$val[nrow(x)])
})
Код-гольф (и незначительное сокращение стека кода): внутренний код filter(data, num <= x)
... или вы предполагаете / делаете вывод, что существует больше кода, который в противном случае использовал бы (и извлекал бы выгоду) из канала magrittr
?
@r2evans Извините. Я использую функцию filter
из dplyr
, как OP. Я работаю над второй частью вопроса ОП, который создает графики.
Я понимаю ... Я просто предложил использовать dplyr::filter
, я просто подумал, что %>%
не нужен в этом (вероятно, слишком упрощенном) примере. Нет пота, на самом деле, скорее всего, это больше.
@r2evans Да, я согласен с вами, что %>%
в данном случае не нужен. Спасибо.
Вероятно, есть гораздо лучший способ решить эту проблему, чем тот, который вы пытаетесь сделать, но чтобы ваша идея заработала, вам просто нужно получить фреймы данных в списке и выполнить итерацию по его индексам.
library(dplyr)
data <- data.frame(num=c(1:6), val=c('1998-99', '1999-00', '2000-01', '2001-02', '2002-03', '2003-04'))
data_lst <- list(
data03 = filter(data, num<=1),
data04 = filter(data, num<=2),
data05 = filter(data, num<=3),
data06 = filter(data, num<=4),
data07 = filter(data, num<=5),
data08 = filter(data, num<=6))
for (i in seq_along(data_lst)) {
print(i)
title = data[2][-1]
print(title)
df <- data_lst[[i]]
plot(df$num, main=title)
}
Пожалуйста, объясните, что вы пытаетесь сделать в конце. То, что вы предлагаете здесь, не очень хорошее манипулирование данными, может потребоваться гораздо больше усилий, чем требуется, и в конце концов может не получиться то, что вам нужно. Одна проблема сейчас заключается в том, что
c(03,04,...)
никогда не будет соответствовать одному из"03"
, `"04" и т. д.