【问题标题】:Reverse the order of some data frame columns颠倒某些数据框列的顺序
【发布时间】:2019-01-26 12:38:57
【问题描述】:

我有一个data.frame,我想计算一个性能指标(例如分位数)。但是,data.frame 的某些列包含您认为“负面”的统计信息 - 一个示例:

r=seq(0,1,0.25)
apply(state.x77,2,function(x) quantile(x,probs = r))
     Population  Income Illiteracy Life Exp Murder HS Grad  Frost      Area
0%        365.0 3098.00      0.500  67.9600  1.400   37.80   0.00   1049.00
25%      1079.5 3992.75      0.625  70.1175  4.350   48.05  66.25  36985.25
50%      2838.5 4519.00      0.950  70.6750  6.850   53.25 114.50  54277.00
75%      4968.5 4813.50      1.575  71.8925 10.675   59.15 139.75  81162.50
100%    21198.0 6315.00      2.800  73.6000 15.100   67.30 188.00 566432.00

收入和预期寿命为正。但是,例如谋杀率是负数,越低越好。我想要这个结果:

     Population  Income Illiteracy Life Exp Murder HS Grad  Frost      Area
0%        365.0 3098.00      2.800  67.9600 15.100   37.80 188.00   1049.00
25%      1079.5 3992.75      1.575  70.1175 10.675   48.05 139.75  36985.25
50%      2838.5 4519.00      0.950  70.6750  6.850   53.25 114.50  54277.00
75%      4968.5 4813.50      0.625  71.8925  4.350   59.15  66.25  81162.50
100%    21198.0 6315.00      0.500  73.6000  1.400   67.30   0.00 566432.00

我使用两个 sweep-functions 和一个 apply 函数来管理它。那太丑了!有没有更优雅的方式?

数据集state.x77 内置在 R 中。

【问题讨论】:

  • 优雅我的意思是,通过使用一个扫描和/或一个应用功能?为了完整起见,我使用了一个权重向量my_weight=c(1,1,-1,1,-1,1,-1,1)
  • 能否请您提供最少的数据(例如使用dput),以便我们重现您的预期输出。
  • @MauritsEvers,state.x77 是一个内置在R 中的数据集。无需包含最少的数据。
  • 我的错。感谢您的澄清。

标签: r dataframe apply


【解决方案1】:

您可以将每一列乘以向量my_weight 中的相应权重。然后取结果的绝对值。由于四分位数已经是quantile 的默认值,因此无需定义概率向量。

my_weight <- c(1, 1, -1, 1, -1, 1, -1, 1)
res <- sapply(seq_along(as.data.frame(state.x77)), function(i)
  abs(quantile(state.x77[, i]* my_weight[i])))
colnames(res) <- colnames(state.x77)

res
#     Population  Income Illiteracy Life Exp Murder HS Grad  Frost      Area
#0%        365.0 3098.00      2.800  67.9600 15.100   37.80 188.00   1049.00
#25%      1079.5 3992.75      1.575  70.1175 10.675   48.05 139.75  36985.25
#50%      2838.5 4519.00      0.950  70.6750  6.850   53.25 114.50  54277.00
#75%      4968.5 4813.50      0.625  71.8925  4.350   59.15  66.25  81162.50
#100%    21198.0 6315.00      0.500  73.6000  1.400   67.30   0.00 566432.00

【讨论】:

  • 我建议做一个小小的改进:使用1:ncol(state.x77) 而不是seq_along(as.data.frame(state.x77)),这样可以提高可读性和速度。否则一如既往的完美:)
  • @5th 谢谢,出于某种原因我没想到。
  • 我使用了这个版本,因为它更灵活。此外,我建议使用lapply 而不是sapply(参见Hadley's explanation)。您使用do.call(cbind,res) 创建矩阵或data.frame
【解决方案2】:

为什么不反转“负面”/“坏”列的值(例如,谋杀列):

r=seq(0,1,0.25)
quantiles <- apply(state.x77,2,function(x) quantile(x,probs = r))
quantiles[, "Murder"] <- rev(quantiles[, "Murder"])

附:显然,这违反了一行一观察的原则,因为我们正在更改数据……但这似乎是您想要的。

【讨论】:

  • 谢谢,这让我走向了正确的方向。 rev 的问题是矢量化答案。但令我惊讶的是an old answer来自我自己的作品:quantiles[,c("Illiteracy","Murder","Frost")]=quantiles[5:1,c("Illiteracy","Murder","Frost")]。如果有人试图单独使用sweepapply 解决此问题,我会稍等。
猜你喜欢
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
  • 2018-01-05
  • 2012-10-10
相关资源
最近更新 更多