循环列R

时间:2015-12-15 16:24:43

标签: r loops

我在data.frame中有一个R,其中包含许多具有数值的列。 像这样:

   A       B      C
0.6057  0.1644  6.93
0.5723  0.117   6.59
0.5614  0.1552  7.02
0.4102  0.1059  5.24
0.4945  0.0857  6.64
0.5157  0.0747  7.06
0.7785  0.1394  5.21
0.5492  0.1557  6.06
0.5411  0.1884  5.68
0.6622  0.148   6.1

对于这些列中的每一列,我想创建一个包含四分位值的新列。使用这个公式,我一次只能在一列上完成它没有问题:

tableOne <- within(data, quartile <-
                    as.integer(cut(A, quantile(A, probs=0:5/5,na.rm=T))))

但由于我100 columns有不同的名字,我想分别循环遍历每一列。

我尝试了一个没有成功的循环:

for(i in names(data)){
  tableOne <- within(data, quarti <- as.integer(cut(i, quantile(i, probs=0:5/5,na.rm=T))))
}

我收到以下错误:

Error in cut.default(i, quantile(i, probs = 0:5/5, na.rm = T)) : 
  'x' must be numeric

我也尝试了应用功能:

df.two <- lapply(df, function(x) within(data, quartile <- as.integer(cut(x, quantile(x, probs=0:5/5,na.rm=T)))))

没有成功:

Error during wrapup: argument "obj" is missing, with no default
Error during wrapup: target context is not on the stack

有关如何在所有列上迭代我的函数并在同一data.frame中获取所有结果的任何建议吗?

非常感谢

1 个答案:

答案 0 :(得分:4)

有关更好的方法,请参阅答案的结尾,这是为了便于理解步骤。

我不确定你愿意做什么,但也许这就是:

df2<- as.data.frame( lapply( df, function(x){
  as.integer( cut(x, quantile(x, probs=(0:5)/5, na.rm=T)))
}))
colnames(df2) <- paste0("quartile_",colnames(df))
df3 <- cbind(df,df2)

给出了:

        A      B    C quartile_A quartile_B quartile_C
1  0.6057 0.1644 6.93          4          5          4
2  0.5723 0.1170 6.59          4          2          3
3  0.5614 0.1552 7.02          3          4          5
4  0.4102 0.1059 5.24         NA          2          1
5  0.4945 0.0857 6.64          1          1          4
6  0.5157 0.0747 7.06          2         NA          5
7  0.7785 0.1394 5.21          5          3         NA
8  0.5492 0.1557 6.06          3          4          2
9  0.5411 0.1884 5.68          2          5          2
10 0.6622 0.1480 6.10          5          3          3

使用的数据:

> dput(df)
structure(list(A = c(0.6057, 0.5723, 0.5614, 0.4102, 0.4945, 
0.5157, 0.7785, 0.5492, 0.5411, 0.6622), B = c(0.1644, 0.117, 
0.1552, 0.1059, 0.0857, 0.0747, 0.1394, 0.1557, 0.1884, 0.148
), C = c(6.93, 6.59, 7.02, 5.24, 6.64, 7.06, 5.21, 6.06, 5.68, 
6.1)), .Names = c("A", "B", "C"), class = "data.frame", row.names = c(NA, 
-10L))

根据下面的@DavidArenburg评论,获得相同结果的更好方法是:

df[paste0("quartile_",colnames(df))] <- lapply(df, function(x) as.integer(cut(x, quantile(x, probs=(0:5)/5, na.rm = TRUE))))

这样可以避免创建新的数据帧并将其复制到最后。

相关问题