新栏目中的条件计数器 - R

时间:2015-09-15 18:02:17

标签: r loops

我想帮助创建一个函数或循环,根据其他列的同一行中的值为新列添加值。目标是为调查数据集创建一种评分系统。

这是一个示例数据框

dfp <- data.frame(id=c("resp1", "resp2", "resp3"), 
                 cat1=c("gov", "biz", "biz"), 
                 cat2=c("dem", "gop", "dem"),
                 liberal=c(0,0,0), 
                 conservative=c(0,0,0))

在上面的集合中,我想象&#34; gov&#34;和&#34; dem&#34;在1点到自由列,而&#34; biz&#34;和&#34; gop&#34;为保守列添加一个点。因此,理想的数据框将是:

dfp <- data.frame(id=c("resp1", "resp2", "resp3"), 
                 cat1=c("gov", "biz", "biz"), 
                 cat2=c("dem", "gop", "dem"),
                 liberal=c(2,0,1), 
                 conservative=c(0,2,1))

我试过一个for循环,但它没有用。

for (i in length(dfp$liberal)){
  if (dfp[i,][,2] == "gov"){
    dfp[i,]$liberal = dfp[i,]$liberal + 1
  }
  if (dfp[i,][,3]=="gop"){
    dfp[i,]$conservative = dfp[i,]$conservative + 1
  }
}

如果我摆脱了&#34;我&#34;迭代器,循环正确添加自由和保守的数字,但它将统一添加到所有行。

感谢您的帮助,如果我能让这个问题更清楚,请告诉我。我对循环有点新意见,如果你碰巧有一个功能可以帮助我诊断我做错了什么,请随意添加你的解释。非常感谢。

4 个答案:

答案 0 :(得分:3)

你甚至不需要“for”循环。尝试

dfp <- data.frame(id=c("resp1", "resp2", "resp3"), 
              cat1=c("gov", "biz", "biz"), 
              cat2=c("dem", "gop", "dem"))

dfp$liberal = as.numeric(dfp$cat1=="gov") + as.numeric(dfp$cat2=="dem")

dfp$conservative = as.numeric(dfp$cat1=="biz") + as.numeric(dfp$cat2=="gop")

答案 1 :(得分:1)

您不需要迭代来创建这些变量。

dfp$liberal <- dfp$cat1 %in% c("gov", "dem") + dfp$cat2 %in% c("gov", "dem")
dfp$conservative <- dfp$cat1 %in% c("gop", "biz") + dfp$cat2 %in% c("gop", "biz")

这行代码在做什么?

  • dfp$cat1 %in% c("gov", "dem")如果cat1相等,则为1,#34; gov&#34;或&#34; dem&#34;否则0。

  • dfp$cat2 %in% c("gov", "dem")如果cat2相等,这是1,#go; gov&#34;或&#34; dem&#34;否则0。

然后你总结两个结果,你有你想要的。创建conservative变量

也是如此

答案 2 :(得分:1)

这样您就可以看到一些索引问题,这里是基于for循环的代码示例。

dfp <- data.frame(id=c("resp1", "resp2", "resp3"), 
                  cat1=c("gov", "biz", "biz"), 
                  cat2=c("dem", "gop", "dem"),
                  liberal=c(0,0,0), 
                  conservative=c(0,0,0))

          #* Use seq_along and not length (or use 1:length())
for (i in seq_along(dfp$liberal)){
  if (dfp$cat1[i] == "gov"){
    dfp$liberal[i] = dfp$liberal[i] + 1
  }
  if (dfp$cat2[i]=="gop"){
    dfp$conservative[i] = dfp$conservative[i] + 1
  }
}

dfp

但其他答案会更有效率。

答案 3 :(得分:1)

使用rowSums的另一个选项。

dfp$liberal <- rowSums(dfp[, 2:3] == c("gov","dem"))
dfp$conservative <- rowSums(dfp[, 2:3] == c("biz","gop"))

<强>输出

     id cat1 cat2 liberal conservative
1 resp1  gov  dem       2            0
2 resp2  biz  gop       0            0
3 resp3  biz  dem       1            1

<强>解释

我们创建两个逻辑向量来评估条件:dfp[, 2:3] == c("gov","dem")dfp[, 2:3] == c("biz","gop")在我们应用函数rowSums时被视为数字。可能它不是最快的选择,但非常简洁。

数据

dfp <- data.frame(id=c("resp1", "resp2", "resp3"), 
                  cat1=c("gov", "biz", "biz"), 
                  cat2=c("dem", "gop", "dem"),
                  liberal=c(0,0,0), 
                  conservative=c(0,0,0))