Получение строк, распознаваемых как имена переменных в R - PullRequest
43 голосов
/ 30 января 2012

Похожие: Строки как ссылки на переменные в R
Возможно связанные: Объединенные выражения для подмножества фрейма данных


Я упростил вопрос по запросу комментария. Вот некоторые примеры данных.

* * 1010

Теперь я хотел бы сделать из них пузырьковый сюжет. У меня есть более сложный набор данных с 3+ цветами и сложными подмножествами, но я делаю что-то вроде этого:

symbols(set1$sq,set1$cu,circles=set1$num,bg="red")
symbols(set2$sq,set2$cu,circles=set2$num,bg="blue",add=T)

Я бы хотел сделать цикл for следующим образом:

colors <- c("red","blue")
sets <- c("set1","set2")
vars <- c("sq","cu","num")

for (i in 1:length(sets)) {
   symbols(sets[[i]][,sq],sets[[i]][,cu],circles=sets[[i]][,num],
   bg=colors[[i]],add=T)
}    

Я знаю, что у вас может быть оцененная переменная для указания столбца (например, var="cu"; set1[,var]; я хочу знать, как получить переменную для определения самого data.frame (и другой для оценки столбца).


Обновление: Пробежал по этот пост на r-блогерах, у которых есть этот пример:

x <- 42
eval(parse(text = "x"))
[1] 42

Теперь я могу сделать что-то вроде этого:

eval(parse(text=paste(set[[1]],"$",var1,sep="")))

Обдумывая это, я нахожу интересным, что следующее не эквивалентно:

vars <- data.frame("var1","var2")
eval(parse(text=paste(set[[1]],"$",var1,sep="")))
eval(parse(text=paste(set[[1]],"[,vars[[1]]]",sep="")))

Я действительно должен сделать это:

eval(parse(text=paste(set[[1]],"[,as.character(vars[[1]])]",sep="")))

Update2: Вышеприведенное работает для вывода значений ... но не при попытке построить график. Я не могу сделать:

for (i in 1:length(set)) {
symbols(eval(parse(text=paste(set[[i]],"$",var1,sep=""))),
       eval(parse(text=paste(set[[i]],"$",var2,sep=""))),
       circles=paste(set[[i]],".","circles",sep=""),
       fg="white",bg=colors[[i]],add=T)
}

Я получаю invalid symbol coordinates. Я проверил класс множества [[1]] и это фактор. Если я сделаю is.numeric(as.numeric(set[[1]])), я получу TRUE. Даже если я добавлю это выше до оператора eval, я все равно получу ошибку. Как ни странно, я могу сделать это:

set.xvars <- as.numeric(eval(parse(text=paste(set[[i]],"$",var1,sep=""))))
set.yvars <- as.numeric(eval(parse(text=paste(set[[i]],"$",var2,sep=""))))
symbols(xvars,yvars,circles=data$var3)

Почему различное поведение при хранении в качестве переменной и выполняемой в символьной функции?

Ответы [ 6 ]

33 голосов
/ 30 января 2012

Вы нашли один ответ, т.е. eval(parse()). Вы также можете исследовать do.call(), который часто проще реализовать. Имейте в виду и полезный инструмент as.name() для преобразования строк в имена переменных.

15 голосов
/ 17 июля 2015

Основной ответ на вопрос в названии - eval(as.symbol(variable_name_as_string)), как использует Джош О'Брайен.например,

var.name = "x"
assign(var.name, 5)
eval(as.symbol(var.name)) # outputs 5

Или проще:

get(var.name) # 5
8 голосов
/ 23 апреля 2013

Если вы хотите использовать строку в качестве имени переменной, вы можете использовать assign:

var1="string_name"

assign(var1, c(5,4,5,6,7))

string_name 

[1] 5 4 5 6 7
8 голосов
/ 30 января 2012

Без каких-либо примеров данных, действительно трудно точно знать , что вы хотите. Например, я вообще не могу предугадать, как выглядит ваш объект set (или он sets).

Тем не менее, помогает ли вообще следующее?

set1 <- data.frame(x = 4:6, y = 6:4, z = c(1, 3, 5))

plot(1:10, type="n")
XX <- "set1"
with(eval(as.symbol(XX)), symbols(x, y, circles = z, add=TRUE))

EDIT

Теперь, когда я вижу вашу реальную задачу, вот строчка с одной строкой, которая будет делать все, что вы хотите, без каких-либо петель for():

with(dat, symbols(sq, cu, circles = num,
                  bg = c("red", "blue")[(num>5) + 1]))

Один бит кода, который может показаться странным, это бит, определяющий цвет фона. Попробуйте эти две строки, чтобы увидеть, как это работает:

c(TRUE, FALSE) + 1
# [1] 2 1
c("red", "blue")[c(F, F, T, T) + 1]
# [1] "red"  "red"  "blue" "blue"
3 голосов
/ 30 января 2012

Подмножество данных и их объединение обратно не требуется.Таковы циклы, так как эти операции векторизованы.Из вашего предыдущего редактирования, я полагаю, вы делаете все это, чтобы сделать пузырьковые графики.Если это правильно, возможно, приведенный ниже пример поможет вам.Если это далеко, я могу просто удалить ответ.

library(ggplot2)
# let's look at the included dataset named trees.
# ?trees for a description
data(trees)
ggplot(trees,aes(Height,Volume)) + geom_point(aes(size=Girth))
# Great, now how do we color the bubbles by groups?
# For this example, I'll divide Volume into three groups: lo, med, high
trees$set[trees$Volume<=22.7]="lo"
trees$set[trees$Volume>22.7 & trees$Volume<=45.4]="med"
trees$set[trees$Volume>45.4]="high"

ggplot(trees,aes(Height,Volume,colour=set)) + geom_point(aes(size=Girth))


# Instead of just circles scaled by Girth, let's also change the symbol
ggplot(trees,aes(Height,Volume,colour=set)) + geom_point(aes(size=Girth,pch=set))

# Now let's choose a specific symbol for each set. Full list of symbols at ?pch
trees$symbol[trees$Volume<=22.7]=1
trees$symbol[trees$Volume>22.7 & trees$Volume<=45.4]=2
trees$symbol[trees$Volume>45.4]=3

ggplot(trees,aes(Height,Volume,colour=set)) + geom_point(aes(size=Girth,pch=symbol))
0 голосов
/ 26 мая 2019

Для меня лучше всего использовать quote() и eval() вместе.

Например, давайте напечатаем каждый столбец, используя for loop:

Columns <- names(dat)
for (i in 1:ncol(dat)){
  dat[, eval(quote(Columns[i]))] %>% print
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...