R:在变量名中使用占位符/计数器来执行循环

时间:2016-01-09 08:29:07

标签: r loops while-loop

我刚刚从STATA迁移到R.我很兴奋,但显然现在面对习惯R及其工作方式的所有这些问题。

在我的工作中,我一直在使用STATA进行数据清理。现在我打算用R做同样的事情。我们使用调查问卷收集大量的原始数据(家庭层面数据)。数据集非常大,通常由许多不同的网格组成(例如,家庭网格,我们为每个家庭成员重复一些问题,例如您的姓名,年龄,教育程度等)。所以你最终可能会遇到诸如此类的问题     Q3_Name_1(家庭成员1的名称)     Q3_Age_1(家庭成员年龄1)     Q3_Edu_1(家庭成员1的教育)

Q3_Name_2 (name for the household member 2)
Q3_Age_2 (age of household member 2)
Q3_Edu_2 (education of household member 2)

Q3_Name_3 (name for the household member 3)
Q3_Age_3 (age of household member 3)
Q3_Edu_3 (education of household member 3)

数据框的结构或多或少看起来如下:

df <- data.frame(ID=c(1, 2, 3,4), Q3_A_1=c(1, 3, 2, 5), 
                 Q3_Age_2=c(1, 4, 2, "Refused"), 
                 Q3_Age_3=c(1, 9, 2, 4), 
                 Q3_Age_4=c(1,11, "Don't know", 5), stringsAsFactors=F)

如果我需要更改家庭网格中的一个问题(例如问题是您的年龄),我很可能需要对家庭网格中的所有其他名称问题进行类似的更改。在这里你最好使用一个循环。您只需编写一次命令,然后R就会应用于网格中的所有这些问题。

我尝试过但失败了。我仍然没有在STATA中得到管理这些循环的原则,关键部分是占位符,类似于'i'来替换每个问题名称末尾的数字。 R中的等价物是什么?我紧紧抓住坚果如下:

i<-1; while(i<=11){
w3$Q3Age_i<-as.character(w3$Q3Age_i)
   w3$Q3Age_i[w3$Q3Age_i == "Refused" | w3$Q3Age_i == "Don't Know"] <-   "NA"
   w3$Q3Age_i<-as.numeric(w3$Q3Age_i)
   i<-i+1
}

也许你也可以使用'重复'之类的东西。但是在这个阶段,我只是不明白你怎么能够理解w3 $ Q3Age_i首先是指w3 $ Q3Age_1然后是w3 $ Q3Age_2等。

任何帮助或提示都会非常感激!

最佳,

的Dom

1 个答案:

答案 0 :(得分:1)

您提供的示例不需要循环作为R矢量化操作。如果我们制作一些虚拟数据:

df = data.frame(ID=c(1, 2, 3, 4),
                Q3_Age_1=c(1, 3, 2, 5), 
                Q3_Age_2=c(1, 4, 2, "Refused"), 
                Q3_Age_3=c(1, 9, 2, 4), 
                Q3_Age_4=c(1, 11, "Don't know", 5),
                stringsAsFactors=F)

然后我们可以更改一列:

df$ans[df$Q3_Age_2 == "Refused"] = NA

鉴于当前的数据结构,这并不理想。

您可以使用reshape2包(http://seananderson.ca/2013/10/19/reshape.html)将数据从宽到长转换:

library(reshape2)
df = melt(df, id.vars="ID")

这意味着您现在可以更轻松地操作答案栏。

但是,如果你想做更复杂的事情并且需要一个循环,我认为更好地定义你的索引列是关键。

获取索引列:

x = strsplit(df$ind, "_")
x = do.call("rbind.data.frame", x)
colnames(x) = c("Question", "Household", "Respondent")
df = cbind(x, df)

迭代您的数据:

# Note lapply returns a list
lapply(unique(df$Respondent), function(i){
    x = df[df$Respondent, ] = i
    # Do what you need to x, your subset of df
    # Make sure your last line returns your result
})

您可能还想查看group_by包中的dplyr

最后,看看如何制作一个可重复的例子(How to make a great R reproducible example?),因为我怀疑你的数据结构很奇怪(也许最好存储在列表中)!