我有包含“年龄差异”列(AgeDiff
)的数据框。数据框如下所示:
library("dplyr")
test <- data.frame("Age1"=c(42, 48, 58, 25, 53, 55, 32, 58, 71, 24, 48, 48, 64, 55, 45, 55, 34, 33, 51, 22),
"Age2"=c(8, 2, 1, 16, 14, 1, 11, 14, 0, 5, 2, 10, 16, 13, 3, 4, 8, 13, 8, 5))
test <- test %>%
mutate(AgeDiff = Age1 - Age2)
对于我正在编写的功能,用户可以输入拒绝最小差和/或拒绝最大差。小于/大于任一阈值的任何年龄差异都会创建“超出范围”的年龄差异。
在我正在做的工作中,任何小于18岁或大于54岁的年龄差异都是“超出范围”的。碰巧的是(我在两组年龄中都使用了随机数生成器),恰好有两个年龄差异太小,两个年龄差异太大。
我可以找到“太年轻”或“太老”的最大值,例如通过比较
TooYoung <- test %>%
filter(AgeDiff < 18) %>%
summarise(Count = n()) %>%
pull(Count)
与
TooOld <- test %>%
filter(AgeDiff > 54) %>%
summarise(Count = n()) %>%
pull(Count)
然后算出哪个值更大。较大的TooYoung
,TooOld
使我可以交换test
数据中的行数。
我可以对test
数据框进行(预)排序,使其AgeDiff
值递增:
test <- test %>%
arrange(AgeDiff)
这给了我想要的顺序,其中数据帧从最极端的AgeDiff
最小值到最极端的AgeDiff
最大值排序。现在我想要做的是交换的最顶部和最底部Age1
值最大的TooYoung
和TooOld
。因为在此例中,我的最大“超出范围”最小值/最大值为2,所以我需要交换:
Age1
在第1行和Age1
第20行Age1
在第2行和Age1
第19行交换是否导致“超出范围”并不重要AgeDiff
。
交换的数据帧可以是任何长度。要进行的交换数量可以是任意数量,包括0。因此,对于任何交换值> 0而言,问题就变成了,
Age1
在第1行Age1
中nrow(foo)
Age1
在第2行Age1
中nrow(foo)-1
AgeDiff
进行交换后将重新计算。我的数据框中还有其他变量,例如Sex
,因此仅Age1
交换值至关重要。
行的重新排序并不重要。唯一的要求是解决方案交换正确的Age1
值对。
我搜索了类似的问题,但发现的问题却大不相同。另一个问题是对于该数据帧的初始百分比的两行互换,两个已知值的相互交换,交换整个行,两个随机选择的行的交换,基于分组变量值互换。在我的问题中,交换次数将确定地计算,但是种群之间的数目不同,Age1
交换值将有所不同,Age1
交换值的数目必须恰好是最大的“超出范围”计数,并且没有分组变量。
编辑添加:假设您有我的数据并完成了排列,您将看到第1行如下所示:
Age1 Age2 AgeDiff
25 16 9
第20行如下所示:
Age1 Age2 AgeDiff
71 0 71
交换后这两行将是:第1行:
Age1 Age2 AgeDiff
71 16 9
第20行:
Age1 Age2 AgeDiff
25 0 71
因此只Age1
交换了两个值。
然后将第2行和第19行交换,最后得到
第2行
Age1 Age2 AgeDiff
58 5 17
对于第19行
Age1 Age2 AgeDiff
22 1 57
该AgeDiff
列将被忽略,因为完成交换后将重新计算该列。
(我也错过了最初的数据帧也应该称为测试,现在我已经解决了。)
我肯定有一种更整洁的方式来做到这一点,但是...
library("dplyr")
test <- data.frame("Age1"=c(42, 48, 58, 25, 53, 55, 32, 58, 71, 24, 48, 48, 64, 55, 45, 55, 34, 33, 51, 22),
"Age2"=c(8, 2, 1, 16, 14, 1, 11, 14, 0, 5, 2, 10, 16, 13, 3, 4, 8, 13, 8, 5))
test <- test %>%
mutate(AgeDiff = Age1 - Age2) %>%
arrange(AgeDiff) %>%
dplyr::mutate(row_no = row_number())
test
swap <- function(df) {
TooYoung <- df %>%
filter(AgeDiff < 18) %>%
summarise(Count = n()) %>%
pull(Count)
TooOld <- df %>%
filter(AgeDiff > 54) %>%
summarise(Count = n()) %>%
pull(Count)
top_bottom <- max(TooYoung, TooOld)
df2 <- df %>%
filter(row_number() > max(row_number()) - top_bottom | row_number() <= top_bottom) %>%
mutate(final_age1 = Age1) %>%
dplyr::select(final_age1, row_no)
df2$row_no <- sort(df2$row_no, decreasing = T)
df_final <- df %>%
left_join(df2) %>%
mutate(final_age1 = ifelse(is.na(final_age1), Age1, final_age1)) %>%
dplyr::select(-Age1, -row_no)
df_final
}
swap(test)
我想给你你想要的?
# Joining, by = "row_no"
# Age2 AgeDiff final_age1
# 1 16 9 71
# 2 5 17 58
# 3 5 19 24
# 4 13 20 33
# 5 11 21 32
# 6 8 26 34
# 7 8 34 42
# 8 10 38 48
# 9 14 39 53
# 10 13 42 55
# 11 3 42 45
# 12 8 43 51
# 13 14 44 58
# 14 2 46 48
# 15 2 46 48
# 16 16 48 64
# 17 4 51 55
# 18 1 54 55
# 19 1 57 22
# 20 0 71 25
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句