我有一个月度股票回报的数据框(每行是一个月):
df:
Stock A Stock B Stock C ....
Jun 1927 1% 2% 3%
Jul 1927 3% 1% 2%
Aug 1927 2% 3% 1%
Sep 1927 5% 2% 9%
...
...
我希望根据回报对每个月的股票进行排名,并根据此创建新的数据框。
这样的事情:
df_rank:
Stock A Stock B Stock C
Jun 1927 1 2 3
Jul 1927 3 1 2
Aug 1927 2 3 1
Sep 1927 2 3 1
我在考虑这样的事情:
df_rank<-data.frame(matrix(NA, nrow = nrow(df), ncol = ncol(df)))
for (i in seq(1:nrow(df))){
df1<-data.frame(rank(df[i,]))
df_rank<-cbind(df_rank,df1)
}
答案 0 :(得分:2)
如果我们将您的数据作为data.frame,并且百分比有一些变化。
month StockA StockB StockC
1 Jun 1927 1% 2% 3%
2 Jul 1927 3% 1% -4%
3 Aug 1927 6.4% 3% 4%
我们可以使用apply在行上运行一个函数。为了使它恢复正确的形状,我们需要应用转置。
t(apply(df[, -1], 1, rank))
StockA StockB StockC
[1,] 1 2 3
[2,] 3 2 1
[3,] 3 1 2
# to replace the data in the data.frame
df[, -1] <- t(apply(df[, -1], 1, rank))
df
month StockA StockB StockC
1 Jun 1927 1 2 3
2 Jul 1927 3 2 1
3 Aug 1927 3 1 2
现在我只是将百分比作为字符值排名。你也可以使用akrun的函数,首先删除%符号,将其设置为数字,然后排名。
t(apply(df[, -1], 1, function(x) rank(as.numeric(sub("[%]", "", x)))))
在这个例子中结果是一样的。但是有很多百分比,用reals代替chars可能会更好。
数据:
df <- structure(list(month = c("Jun 1927", "Jul 1927", "Aug 1927"),
StockA = c("1%", "3%", "6.4%"),
StockB = c("2%", "1%", "3%"),
StockC = c("3%", "-4%", "4%")),
.Names = c("month", "StockA","StockB", "StockC"),
class = "data.frame", row.names = c(NA, -3L))
答案 1 :(得分:-1)
我们可以删除%
,然后使用rank
:
df[] <- t(sapply(as.data.frame(t(df)),
function(x) rank(as.numeric(sub("[%]", "", x)))))