【问题标题】:R: Nested if else statements on list of data framesR:在数据框列表上嵌套 if else 语句
【发布时间】:2015-12-16 03:40:16
【问题描述】:

我有一个数据框列表,它们都具有相同的结构。我需要根据另一个变量的值在每个数据帧中重新编码一个变量。我在这里找到了让我很接近的解决方案,但经过几个小时后,我仍然不够努力。

我的数据框如下所示:

$Test14
   Class Total
1    201     1
2    203    14
3    204     3
4    205     7
5    206     7
6    207     1
7    211     2
8    212     1
9    213    16
10   288    27
11   299     9
12   517     1
13   592     2
14   593     8

每个 Class 代码都属于一个更大的 MajorClass 类别。我正在尝试附加另一个 MajorClass,以便我可以将数据转换为简单的英语。所以是这样的:

$Test14
    Class   Total   MajorClass
1   201         1   Reg Residential
2   203        14   Reg Residential
3   204         3   Reg Residential
4   205         7   Reg Residential
5   206         7   Reg Residential
6   207         1   Reg Residential
7   211         2   Reg Residential
8   212         1   Reg Residential
9   213        16   NonReg Residential
10  288        27   NonReg Residential
11  299         9   NonReg Residential
12  517         1   Commercial
13  592         2   Commercial
14  593         8   Industrial

我的想法是尝试使用 lapply 代替 for 循环来获取每行的 MajorClass,然后使用 cbind 稍后将它们全部拉回。我来的关闭是使用以下代码:

> MajorClass <- lapply(mydata, function(i) {
>     i$MajorClass <- ""
>     if (i$Class == '200' || i$Class == '202' || i$Class == '203' || i$Class       == '204' || i$Class == '205' || i$Class == '206' || i$Class ==
> '207' || i$Class == '208' || i$Class == '209' || i$Class == '210' ||
> i$Class == '211' || i$Class == '212' || i$Class == '216' || i$Class ==
> '234'  || i$Class == '278'  || i$Class == '295') 
>          i$MajorClass <- "Reg Residential"
>     else
>         if (i$Class == '239' || i$Class == '240' || i$Class == '241' || i$Class == '201' || i$Class == '213' || i$Class == '224' || i$Class
> == '225' || i$Class == '236' || i$Class == '288' || i$Class == '290' || i$Class == '297' || i$Class == '299') 
>             i$MajorClass <- "NonReg Residential" ... and so on ...

但它只为每个数据帧中的最后一条记录返回一个值。我对此尝试了多种变体,并尝试使用 for 循环,但均无济于事。另外,我的(有限的)理解是使用 apply 函数而不是 for 循环更有效。

任何帮助或指出正确的方向将不胜感激。正如我所说,我在这个网站和其他网站上进行了很多搜索,结果很接近但还不够接近。再次感谢!

【问题讨论】:

    标签: r for-loop dataframe lapply


    【解决方案1】:

    我假设您有一个 Vicent Boned 描述的参考表。您可以使用 base R 来完成这项工作。

    test$MajorClass <- factor(test$class, levels=reference_table$class, labels=reference_table$MajorClass)
    

    【讨论】:

      【解决方案2】:

      您要做的是将一个表中的值匹配到另一个表中,这可以通过join 轻松完成。这将通过一个公共(且名称相同)列匹配两个表的元素。

      为此,您需要一个参考表,其中每个不同的class 都有其关联的MajorClass。 (我已经生成了一些虚拟数据)

      #install.packages("dplyr")
      library(dplyr)
      
      test <- list(test14 = data.frame(class =  c("201", "203","205"), total=c(1,3,7),
                                   stringsAsFactors = F))
      reference_table <- data.frame(class = c("201","202","203","204","205"),
                                MajorClass=c("Reg","Reg","NonReg","comercial","comercial"),
                                stringsAsFactors = F)
      

      现在您可以使用lapply 将其与每个数据框匹配

      output.list <- lapply(test, function(x) left_join(x, reference_table, by="class"))
      $test14
        class total MajorClass
      1   201     1        Reg
      2   203     3     NonReg
      3   205     7  comercial
      

      或者将列表中的所有数据框合并为一个(如果它们具有相同的结构,您可以这样做),然后一次匹配所有表。

      data <- bind_rows(test)
      output <- left_join(data, reference_table, by="class")
      
        class total MajorClass
        (chr) (dbl)      (chr)
      1   201     1        Reg
      2   203     3     NonReg
      3   205     7  comercial
      

      【讨论】:

      • 或者不使用dplyr(但仍然假设引用表),您可以简单地使用test$MajorClass &lt;- factor(test$class, levels=reference_table$class, labels=reference_table$MajorClass)。在基础 R 中有替代方案总是好的。
      • 当然!如果我使用 SQL,这就是我的想象。我想多了。真的很感谢文森特。
      • @antoine-sac,我很少使用factors,也从未想过以这种方式使用它们!谢谢!
      猜你喜欢
      • 2013-03-08
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      • 2015-09-03
      • 1970-01-01
      相关资源
      最近更新 更多