R:在数据帧列表上嵌套if else语句

时间:2015-09-18 21:30:29

标签: r for-loop dataframe lapply

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

我的数据框架如下所示:

$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

每个类代码都属于较大的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循环更有效。

任何帮助或指向正确的方向将不胜感激。就像我说的那样,我在这个网站和其他网站上搜索了很多,并且接近但不够接近。再次感谢!

2 个答案:

答案 0 :(得分:1)

您要做的是将一个表中的值与另一个表匹配,这可以通过var myList = (from s in new List<string> { "alpha", string.Empty, "gamma" } where !String.IsNullOrWhiteSpace(s) select s); 轻松完成。这通过公共(同名)列匹配两个表的元素。

为此,您需要一个参考表,其中每个不同的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

答案 1 :(得分:0)

我假设你有一个参考表,正如Vicent Boned描述的那样。您可以使用基数R来完成这项工作。

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