我经常需要从R中的data.frame中选择一组变量。 我的研究是在社会和行为科学中,拥有一个包含数百个变量的数据框架是很常见的(例如,一系列调查问题,人口统计项目,绩效指标等都有项目级信息。 。等。)。
作为分析的一部分,我经常想要选择变量的子集。 例如,我可能想要:
现在,我知道有很多方法可以编写代码来选择变量的子集。 Quick-r has a nice overview of common ways of extracting variable subsets from a data.frame
例如,
myvars <- c("v1", "v2", "v3")
newdata <- mydata[myvars]
但是,我对此过程的效率感兴趣,特别是在您可能需要从data.frame中提取20个左右的变量时。变量的命名约定通常不直观,特别是在您从其他人继承数据集的情况下,因此您可能会感到疑惑,变量Gender
,gender
,sex
, GENDER
,gender1
等
将此乘以需要提取的20个变量,记忆变量名称的任务变得比它需要的更复杂。
为了使以下讨论具体,我将使用bfi
包中的psych
data.frame。
library(psych)
data(bfi)
df <- bfi
head(df, 1)
A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 E1 E2 E3 E4 E5 N1 N2 N3 N4 N5 O1 O2 O3 O4
61617 2 4 3 4 4 2 3 3 4 4 3 3 3 4 4 3 4 2 2 3 3 6 3 4
O5 gender education age
61617 3 1 NA 16
A1, A2, A3, A5, C2, C3, C5, E2, E3, gender, education, age
?我目前使用的是一系列策略。
当然,有时我可以利用变量的数字位置或命名约定之类的东西,并使用grep
来选择或paste
来构造。但有时我需要一个更通用的解决方案。我一直使用以下内容:
在早期,我曾经打电话给names(df)
,复制引用的变量名,然后编辑,直到我得到我想要的。
有时候我会有一个单独的data.frame,它将每个变量存储为一行,并且包含变量名称,变量标签的列,并且它有一个列,指示是否应该为特定分析保留变量。然后,我可以过滤该include
变量并提取变量名称的向量。我发现这在我开展心理测试和各种迭代时特别有用,我希望包含或排除某些项目。
由于Hadley Wickham once pointed out to me dput
是一个不错的选择;例如,dput(names(df))
优于names(df)
,因为它会输出已经采用c("var1", "var2", ...)
格式的列表:
dput(names(df))
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5",
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1",
"O2", "O3", "O4", "O5", "gender", "education", "age")
然后可以将其复制到脚本中并进行编辑。
我猜dput
是一个非常好的变量选择策略。这个过程的效率在很大程度上取决于你将文本复制到脚本中的能力,然后将名称列表编辑到所需的名称。
但是,我仍然记得基于GUI的变量选择系统的效率。
例如,在SPSS中,当您与对话框进行交互时,您可以使用鼠标指向并单击所需的数据集中的变量。您可以按住Shift键单击以选择一系列变量,您可以按住shift并按向下键选择一个或多个变量,依此类推。然后,您可以按Paste
,并将带有解压缩变量名称的命令粘贴到脚本编辑器中。
guiselect(df)
这样的东西打开一个用于变量选择的gui窗口),并返回一个选择的变量名称向量{ {1}}?c("var1", "var2", ...)
是在R中选择一组变量名的最佳选择吗?或者有更好的方法吗?更新(2017年4月):我已经发布了自己对good strategy below的理解。
答案 0 :(得分:23)
我个人是myvars <- c(...)
的粉丝,然后从那里使用mydf[,myvars]
。
然而,这仍然需要您输入初始变量名称(即使只是一次),并且就我读到您的问题而言,正是您要问的是这个初始的“选择变量名称”。
一个简单的简单的GUI设备 - 我最近被介绍到menu
函数,这是一个简单的简单的GUI设备,用于选择一个对象一系列选择。尝试menu(names(df),graphics=TRUE)
查看我的意思(返回列号)。如果由于某种原因你的系统无法处理图形,它甚至可以提供一个很好的文本界面(尝试使用graphics=FALSE
看看我的意思。)
然而,这对您的用途有限,因为您只能选择一个列名。
要选择多个,您可以使用select.list
(在?menu
中提及作为进行多项选择的替代方法):
# example with iris data (I don't have 'psych' package):
vars <- select.list(names(iris),multiple=TRUE,
title='select your variable names',
graphics=TRUE)
这也需要graphics=TRUE
选项(单击要选择的所有项目)。
它返回变量的名称。
答案 1 :(得分:10)
您可以使用select.list()
,如下所示:
DF <- data.frame(replicate(26,list(rnorm(5))))
names(DF) <- LETTERS
subDF <- DF[select.list(names(DF), multiple=TRUE)]
答案 2 :(得分:5)
我使用以下策略在R效率中进行变量选择。
对于某些变量集,我有每个变量一行的数据框。例如,我可能会进行100项个性测试。元数据包括R中的变量名称以及所有评分信息(例如,项目是否应该反转等等)。然后,我可以从此元数据中提取项目和比例名称的变量名称。
在每个项目中,我都有一个名为v
的列表,用于存储命名的变量集。
然后在任何需要一组变量的分析中,我只能引用命名列表。这也使代码更可靠,因为如果变量名称发生变化,那么所有的偶然分析都会发生变化。它还有助于在变量的排序方式中创建一致性。
这是一个简单的例子:
v <- list()
v$neo_items <- meta.neo$id
v$ds14_items <- meta.ds14$id
v$core_items <- c(v$neo_items, v$ds14_items)
v$typed_scales <- c("na", "si")
v$typed_all <- c("typed_continuous_sum", "na", "si")
v$neo_facets <- sort(unique(meta.neo$facet))
v$neo_factors <- c("agreeableness", "conscientiousness",
"extraversion", "neuroticism", "openness")
v$outcomes_scales <- c("healthbehavior", "socialsupport",
"physical_symptoms", "psychological_symptoms")
从上面的例子可以看出几点:
meta.neo$id
unique
值来从该列派生变量名称。dput(names(df)
df
是我的data.frame来生成字符名称的向量,然后存储在变量列表中。 v$
,然后按Tab键或v$
以及列表名称的某些部分。使用变量列表非常简单,但R中的某些函数以不同的方式指定变量名称。
简单和标准方案涉及向data.frame子集提供变量名称列表。例如,
cor(data[,v$mylist])
cor(data[,v$predictors], data[,v$outcomes])
对于需要公式的函数来说,这有点棘手。您可能需要编写一个函数。例如:
v <- list()
v$predictors <- c("cyl", "disp")
f <- as.formula(paste("mpg ~", paste(v$predictors, collapse = " + ")))
lm(f, mtcars)
您还可以在sapply
和lapply
等函数中使用变量列表(可能是tidyverse等价物)。例如,
使用以下命令创建描述性统计表:
sapply(mydata[, v$outcomes], function(X) c(mean = mean(X), sd = sd(X)))
dput
仍然有用对于即席变量,或者即使您只是编写代码来创建变量列表,dput
仍然非常有用。
标准代码为dput(names(df))
,其中df
是您的data.frame。例如:
dput(names(mtcars))
可生产
c("mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am",
"gear", "carb")
然后,您可以编辑此字符串以提取所需的变量。 这样做的另一个好处是可以减少代码中的输入错误。这是非常重要的一点。您不想花费大量时间尝试调试仅仅是错字导致的代码。此外,错误输入变量名称时的Rs错误消息很糟糕。它只是说&#34;选择了未定义的列&#34;。它没有告诉你哪些变量名称是错误的。
如果您有大量变量,您还可以使用一系列字符串搜索功能来提取变量名称的子集:
例如
> library(psych)
> dput(names(bfi)) #all items
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5",
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1",
"O2", "O3", "O4", "O5", "gender", "education", "age")
> dput(grep("^..$", names(bfi), value = TRUE)) # two letter variable names
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5",
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1",
"O2", "O3", "O4", "O5")
> dput(grep("^E.$", names(bfi), value = TRUE)) # E items
c("E1", "E2", "E3", "E4", "E5")
> dput(grep(".5$", names(bfi), value = TRUE)) # 5th items
c("A5", "C5", "E5", "N5", "O5")
当我从其他人那里获得数据文件时,变量名称通常缺少约定或使用约定,这使得在R中使用的变量不太有用。我使用的一些规则:
所有这些步骤通常使变量选择更容易,因为要记住的不一致性更少。
对于个别变量,我通常使用数据框中的自动完成功能。例如,df$
并按下标签。
我尝试使用允许我尽可能使用自动完成的编码风格。我不喜欢要求我在不使用自动完成的情况下知道变量名称的函数。例如,在对data.frame进行子集化时,我更喜欢
df[ df$sample == "control", ]
到
subset(df, sample == "control")
因为我可以自动填写变量名称&#34; sample&#34;在顶部示例中,但不在第二个示例中。
答案 3 :(得分:3)
如果你想要一个忽略变量的方法并且可能根据它们的'stems'选出变量的方法,那么使用适当的正则表达式模式和ignore.case- = TRUE和value = TRUE with grep:
dfrm <- data.frame(var1=1, var2=2, var3=3, THIS=4, Dont=5, NOTthis=6, WANTthis=7)
unlist(sapply( c("Want", "these", "var"),
function(x) grep(paste("^", x,sep=""), names(dfrm), ignore.case=TRUE, value=TRUE) ))
#----------------
Want var1 var2 var3 # Names of the vector
"WANTthis" "var1" "var2" "var3" # Values matched
> dfrm[desired]
WANTthis var1 var2 var3
1 7 1 2 3
答案 4 :(得分:0)
您的意思是select
吗?
sub_df = subset(df, select=c("v1","v2","v3"))