【问题标题】:How to run a for-loop through a string vector of a data frame in R?如何通过R中数据框的字符串向量运行for循环?
【发布时间】:2014-09-29 14:42:01
【问题描述】:

我正在尝试做一些非常简单的事情:通过名称向量运行循环并在我的代码中使用这些名称。

geo = c(rep("AT",3),rep("BE",3))
time = c(rep(c("1990Q1","1990Q2","1990Q3"),2))
value = c(1:6)
Data <- data.frame(geo,time,value)

我的真实数据集有 14 个国家和 75 个时间段。我想找到一个函数,例如遍历国家,然后对它们进行子集化,这样我就有了单个数据集,例如:

data_AT <- subset(Data, (Data$geo=="AT"))
data_BE <- subset(Data, (Data$geo=="BE"))

但是有一个循环,最好有一个解决方案,我也可以应用于其他功能:-)

在我看来,这应该是这样的:

codes <- unique(Data$geo)
for (i in 1:length(codes))
{k <- codes[i]
data_(k) <- subset(Data, (Data$geo==k))}

但是子集不能像这样工作,其他函数也不能。我认为我的问题是我不知道如何解决“k”作为我的代码的一部分所采用的相应名称(例如“AT”)。如果可能的话,我将非常感谢一个关于如何通过包含文本的向量运行函数并在我的代码中使用该向量的每个元素的通用解决方案的答案。也许在应用功能的方向?虽然我也没有走得太远......

任何帮助将不胜感激!

【问题讨论】:

    标签: r for-loop panel


    【解决方案1】:

    在 R 中,您通常会使用 list 的 data.frames 而不是几个单独的 data.frames:

    lst <- split(Data, Data$geo)
    lst
    #$AT
    #  geo   time value
    #1  AT 1990Q1     1
    #2  AT 1990Q2     2
    #3  AT 1990Q3     3
    #
    #$BE
    #  geo   time value
    #4  BE 1990Q1     4
    #5  BE 1990Q2     5
    #6  BE 1990Q3     6
    

    现在您可以通过键入以下内容访问每个元素(即 data.frame):

    lst[["AT"]]
    #  geo   time value
    #1  AT 1990Q1     1
    #2  AT 1990Q2     2
    #3  AT 1990Q3     3
    

    如果您有一个国家名称向量,您想在值列中添加 +1,您可以这样做:

    cntrs <- c("BE", "AT")
    lst[cntrs] <- lapply(lst[cntrs], function(x) {x$value <- x$value + 1; return(x)} )
    #$BE
    #  geo   time value
    #4  BE 1990Q1     5
    #5  BE 1990Q2     6
    #6  BE 1990Q3     7
    #
    #$AT
    #  geo   time value
    #1  AT 1990Q1     2
    #2  AT 1990Q2     3
    #3  AT 1990Q3     4
    

    编辑:如果你真的想坚持使用 for 循环,我建议不要将数据拆分成几个单独的 data.frame,而是像这样在整个数据集上运行循环:

    cntrs <- "BE"  
    
    for(i in cntrs){
       Data$value[Data$geo == i] <- Data$value[Data$geo == i] + 1
    }
    

    【讨论】:

    • 谢谢!这是子集案例的一个很好的解决方案,但对我的一般问题没有帮助。假设我有更多国家/地区,并希望为其中一些国家/地区的价值增加 +1。我想创建一个向量,然后通过该向量运行一个循环,并为这些国家的值添加 +1。这种语法如何工作?
    • 非常感谢!但是有没有办法循环这个?我可以想象一百种情况,我可以使用循环而不必每次都学习和编写不同的函数。例如,通过不同的子样本运行 lm() 并为观星者保存不同的模型,或者为不同的国家保存地块等等……我真的在寻找一个循环! :-)
    • 可以循环使用,但这实际上在 R 中被认为是不好的做法。如果您将来要使用 R,绝对值得学习 *apply 系列函数,尤其是applysapplylapply。如果您真的想坚持使用循环,我至少建议不要将数据拆分为许多单独的 data.frame,而是将它们保持在一个循环中并且仅作为子集。我将发布一个示例。
    • 太好了,谢谢!并感谢应用功能的提示,我想从长远来看没有办法解决它......:s
    【解决方案2】:

    我也将循环用于类似目的。也许这不是最快的方法,但至少我理解它——例如,在为不同的子集保存图时。

    不需要遍历向量的长度,你可以遍历向量本身。要将字符串转换为变量名,可以使用assign。

    geo = c(rep("AT",3),rep("BE",3))
    time = c(rep(c("1990Q1","1990Q2","1990Q3"),2))
    value = c(1:6)
    Data <- data.frame(geo,time,value)
    
    codes <- sort(unique(Data$geo))
    for (k in codes) {
     name<-paste("data", k, sep="_")
     assign(name, subset(Data, (Data$geo==k)))
    }
    

    顺便说一句,从包 dplyr 中过滤比子集快得多!

    【讨论】:

    • 谢谢谢谢谢谢!这正是我一直在寻找的。我现在正在阅读有关 xapply 函数的教程以安抚 R 纯粹主义者,但拥有有效且我理解的代码仍然很棒...... :-D
    • 是的,我也在学习 apply 并尝试尽可能使用 apply(vapply 是我的最爱),但不知道如何将 apply 用于这样的目的。花两天时间来优化一些足够好的东西是没有用的。
    猜你喜欢
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多