使用for循环分解数据框

时间:2014-06-23 10:09:44

标签: r loops for-loop dataframe

我有一个与此类似的数据集:

   city var value
    a   var1    0.19
    b   var1    0.67
    c   var1    0.19
    a   var2    0.14
    b   var2    0.38
    c   var2    0.27
    a   var3    0.59
    b   var3    0.42
    c   var3    0.27
    a   var4    0.28
    b   var4    0.37
    c   var4    0.91

我需要与其他城市创建城市b的不同数据框架(例如城市b与城市a,城市b与城市c等)。非常重要的是,城市b首先出现在我稍后进行的某些代数运算的所有变量中。

带城市a的示例城市b:

city    var value
b   var1    0.67
a   var1    0.19
b   var2    0.38
a   var2    0.14
b   var3    0.42
a   var3    0.59
b   var4    0.37
a   var4    0.28

带城市c的示例城市b:

city    var value
b   var1    0.67
c   var1    0.19
b   var2    0.38
c   var2    0.27
b   var3    0.42
c   var3    0.27
b   var4    0.37
c   var4    0.91

我尝试了以下(我的第一个循环之一),但它没有用。 :

for (i in unique(df$city)) {
  paste0("cityb",i) <- (df[df$city %in% c("cityb", "i"), ])
}

你知道它为什么不起作用吗?非常感谢任何帮助或建议。

2 个答案:

答案 0 :(得分:2)

你走了:

第1步:重新创建数据

dat <- read.table(text="
city var value
a   var1    0.19
b   var1    0.67
c   var1    0.19
a   var2    0.14
b   var2    0.38
c   var2    0.27
a   var3    0.59
b   var3    0.42
c   var3    0.27
a   var4    0.28
b   var4    0.37
c   var4    0.91
", header=TRUE)

第2步:重新调整城市,使b成为第一级。您将在步骤3中使用此功能,以确保按正确的顺序对城市进行排序。

dat$city <- relevel(dat$city, "b")

步骤3:使用lapply创建数据框列表。您传递给lapply的函数会创建子集(使用类似于您在问题中尝试的逻辑),然后使用order()函数对其进行排序:

lapply(
  setdiff(levels(dat$city), "b"),
  function(i){
    ret <- dat[dat$city %in% c("b", i), ]
    ret[order(ret$var, ret$city), ]
  })

结果:

[[1]]
   city  var value
2     b var1  0.67
1     a var1  0.19
5     b var2  0.38
4     a var2  0.14
8     b var3  0.42
7     a var3  0.59
11    b var4  0.37
10    a var4  0.28

[[2]]
   city  var value
2     b var1  0.67
3     c var1  0.19
5     b var2  0.38
6     c var2  0.27
8     b var3  0.42
9     c var3  0.27
11    b var4  0.37
12    c var4  0.91

答案 1 :(得分:0)

如果city列不是factor,您可以:(略微修改Andrie's代码:

lst <- lapply(letters[c(1, 3)], function(i) {
x1 <- rbind(dat[dat$city == "b", ], dat[dat$city == i, ])
indx <- seq(1, nrow(x1), by = 4) + rep(0:3, each = 2)
x1[indx, ]
}), paste0("dat", 1:2))

list2env(lst, envir=.GlobalEnv)
#<environment: R_GlobalEnv>

 str(dat1)
 #'data.frame': 8 obs. of  3 variables:
 #$ city : chr  "b" "a" "b" "a" ...
 #$ var  : chr  "var1" "var1" "var2" "var2" ...
 #$ value: num  0.67 0.19 0.38 0.14 0.42 0.59 0.37 0.28
 str(dat2)
 # 'data.frame':    8 obs. of  3 variables:
 # $ city : chr  "b" "c" "b" "c" ...
 # $ var  : chr  "var1" "var1" "var2" "var2" ...
 # $ value: num  0.67 0.19 0.38 0.27 0.42 0.27 0.37 0.91