r - 如何根据这些列子集的排序来改变 R 中的列?
问题描述
首先,假设我们有一个这样的数据集:
data <- data.frame(
id = 1:5,
time = c(0.1, 0.2, 0.1, 0.1, 0.2),
obj_a_size = c(1, 3, 8, 4, 2),
obj_a_cuteness = c(3, 6, 4, 1, 2),
obj_b_size = c(5, 4, 4, 2, 5),
obj_b_cuteness = c(6, 2, 10, 9, 6),
obj_c_size = c(3, 6, 7, 1, 6),
obj_c_cuteness = c(10, 1, 6, 8, 8)
)
它有关于整个实验的列(如time
)和特定于对象的列(如X_size
和X_cuteness
)。不过,这些对象是随机排序的,所以我想改变这些列,以分别为每个实验按大小排序对象。我期望的结果是这样的:
data <- data.frame(
id = 1:5,
time = c(0.1, 0.2, 0.1, 0.1, 0.2),
obj_max_size = c(5, 6, 8, 4, 6),
obj_max_cuteness = c(6, 1, 4, 1, 8),
obj_2nd_size = c(3, 4, 7, 2, 5),
obj_2nd_cuteness = c(10, 2, 6, 9, 6),
obj_min_size = c(1, 3, 3, 1, 2),
obj_min_cuteness = c(3, 6, 10, 8, 2)
)
请注意,可爱度不是按降序或升序排列的,但我希望将可爱度视为对象的一部分并设置obj_max_cuteness = obj_2_cuteness
在任何地方obj_max_size = obj_2_size
,依此类推。
预先知道对象的数量(其中有四个),列也是已知的,并且有四个列描述每个对象。没有丢失的数据。如有必要,我愿意使用任何软件包。此外,原始数据集约为 500k x 30,因此快速或内存友好代码的奖励积分。
编辑:有些人注意到描述不是很清楚。我所追求的是一点面向对象的东西:在上面的例子中,实验中的每个对象都可以这样描述(X
意味着obj_X_
它属于实验号X
):
obj_1_a = {"size": 1, "cuteness": 3}
obj_1_b = {"size": 5, "cuteness": 6}
obj_1_c = {"size": 3, "cuteness": 10}
obj_2_a = {"size": 3, "cuteness": 6}
...
我想按大小重新排序它们,以便(在结果数据框中):
obj_1_max = {"size": 5, "cuteness": 6}
obj_1_2nd = {"size": 3, "cuteness": 10}
obj_1_min = {"size": 1, "cuteness": 3}
obj_2_max = {"size": 6, "cuteness": 1}
...
解决方案
这就是你所追求的吗?最小值和最大值计算很简单。要找到第二个最大值,您需要做更多的工作。我对第二个值的解释是它是排序和唯一值的第二个值。我的输出与您的不同,但这可能是由于您对第二个值的含义的不同解释。我的阅读:您正在寻找从最大值下降的第一个值;来自 3 列(大小、可爱度)的组。
library(dplyr)
data <- data.frame(
id = 1:5,
time = c(0.1, 0.2, 0.1, 0.1, 0.2),
obj_a_size = c(1, 3, 8, 4, 2),
obj_a_cuteness = c(3, 6, 4, 1, 2),
obj_b_size = c(5, 4, 4, 2, 5),
obj_b_cuteness = c(6, 2, 10, 9, 6),
obj_c_size = c(3, 6, 7, 1, 6),
obj_c_cuteness = c(10, 1, 6, 8, 8)
)
obj_max_size <- data %>%
pivot_longer(cols = contains('size')) %>%
group_by(id) %>%
summarise(obj_max_size = max(value)) %>%
ungroup() %>%
select(obj_max_size)
obj_min_size <- data %>%
pivot_longer(cols = contains('size')) %>%
group_by(id) %>%
summarise(obj_min_size = min(value)) %>%
ungroup() %>%
select(obj_min_size)
obj_2nd_size <- data %>%
pivot_longer(cols = contains('size')) %>%
group_by(id) %>%
distinct(value) %>%
arrange(desc(value)) %>%
slice(2) %>%
ungroup() %>%
select(obj_2nd_size = value)
obj_max_cuteness <- data %>%
pivot_longer(cols = contains('cuteness')) %>%
group_by(id) %>%
summarise(obj_max_cuteness = max(value)) %>%
ungroup() %>%
select(obj_max_cuteness)
obj_min_cuteness <- data %>%
pivot_longer(cols = contains('cuteness')) %>%
group_by(id) %>%
summarise(obj_min_cuteness = min(value)) %>%
ungroup() %>%
select(obj_min_cuteness)
obj_2nd_cuteness <- data %>%
pivot_longer(cols = contains('cuteness')) %>%
group_by(id) %>%
distinct(value) %>%
arrange(desc(value)) %>%
slice(2) %>%
ungroup() %>%
select(obj_2nd_cuteness = value)
output <- bind_cols(id = data$id, obj_max_size, obj_min_size, obj_2nd_size, obj_max_cuteness, obj_min_cuteness, obj_2nd_cuteness)
看起来output
像这样:
> output
# A tibble: 5 x 7
id obj_max_size obj_min_size obj_2nd_size obj_max_cuteness obj_min_cuteness obj_2nd_cuteness
<int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 5 1 3 10 3 6
2 2 6 3 4 6 1 2
3 3 8 4 7 10 4 6
4 4 4 1 2 9 1 8
5 5 6 2 5 8 2 6
推荐阅读
- node.js - 正确的方法来弄清楚一个承诺有什么拒绝?
- matlab - 如何修复 MATLAB 中的负输入错误
- html - 我的操作按钮不断改变网格对象的大小
- ckeditor - 配置 CKEditor pasteFilter 以去除某些内联样式
- php - 将第二个 url 链接到与不同 url 相同的目录,而不将内容复制到第二个目录?
- javascript - 如何将 Array 转换为 ES6 新的 Map 类型?
- android - 从后台启动混合 Android 应用程序时 HTTP 调用中的奇怪行为
- ios - 昵称的 UITextField
- actions-on-google - 在用户提供输入之前,Google 新 SignIn() 上的操作正在取消
- ruby-on-rails - Unicorn fcntl: Errno::EPERM: Operation not allowed