假设我有一个数据.框架如下:

df <- data.frame(group = rep(c("A", "B"), each = 10),
                   value = c(0, 0, 11, 5, 9, 8, 0, 6, 0, 9, 
                             4, 0, 0, 0, 18, 1, 1, 0, 3, 6), 
                   index = c(0, 4, 3, 3, 2, 6, 0, 1, 0, 5, 
                             3, 0, 6, 0, 2, 4, 5, 0, 2, 1))

使用dplyr,我想根据每个组添加一个新列,它提取列"VALUE"的倒序非零值的第n个值,将列"INDEX"中的非零值用作索引n.

我想要的输出如下所示:

   group value index column_wanted
1      A      0     0             0
2      A      0     4             8
3      A     11     3             9
4      A      5     3             9
5      A      9     2             9
6      A      8     6             5
7      A      0     0             0
8      A      6     1            11
9      A      0     0             0
10     A      9     5             6
11     B      4     3             4
12     B      0     0             0
13     B      0     6             1
14     B      0     0             0
15     B     18     2             6
16     B      1     4             3
17     B      1     5             1
18     B      0     0             0
19     B      3     2             6
20     B      6     1            18

该任务可以通过首先创建只包含非零值的df子集,然后创建新列来完成,如下所示:

df_no0 <- df %>% filter(index != 0)

df_no0 <- df_no0 %>% 
  group_by(group) %>% 
  mutate(correct_col = rev(sort(value))[index])

df_no0

# A tibble: 14 × 4
# Groups:   group [2]
   group value index correct_col
   <chr>  <dbl> <dbl>       <dbl>
 1 A          0     4           8
 2 A         11     3           9
 3 A          5     3           9
 4 A          9     2           9
 5 A          8     6           5
 6 A          6     1          11
 7 A          9     5           6
 8 B          4     3           4
 9 B          0     6           1
10 B         18     2           6
11 B          1     4           3
12 B          1     5           1
13 B          3     2           6
14 B          6     1          18

然后,我们可以将其转换为仅包含零值的df的子集:

df_just0 <- df %>% filter(index == 0)

df_final <- df_no0 %>% 
  rbind(df_just0 %>% mutate(correct_col = 0))
  arrange(group)

df_final

# A tibble: 20 × 4
# Groups:   group [2]
   group value index correct_col
   <chr>  <dbl> <dbl>       <dbl>
 1 A          0     4           8
 2 A         11     3           9
 3 A          5     3           9
 4 A          9     2           9
 5 A          8     6           5
 6 A          6     1          11
 7 A          9     5           6
 8 A          0     0           0
 9 A          0     0           0
10 A          0     0           0
11 B          4     3           4
12 B          0     6           1
13 B         18     2           6
14 B          1     4           3
15 B          1     5           1
16 B          3     2           6
17 B          6     1          18
18 B          0     0           0
19 B          0     0           0
20 B          0     0           0

这为我提供了所需的输出(行顺序并不重要).

这是可行的,但我正在寻找一种"更干净"和更短的解决方案,避免将数据"切割"成几个部分,并最终将它们重新绑定(真正的数据有数百个组和数千个观察).

所以我try 了这样的方法:

df %>%
  group_by(group) %>%
  mutate(wrong_column = ifelse(index == 0, 0, 
            rev(sort(value[value != 0]))[index[index != 0]]))

# A tibble: 20 × 4
# Groups:   group [2]
   group value index wrong_column
   <chr>  <dbl> <dbl>        <dbl>
 1 A          0     0            0
 2 A          0     4            9
 3 A         11     3            9
 4 A          5     3            9
 5 A          9     2            5
 6 A          8     6           11
 7 A          0     0            0
 8 A          6     1            8
 9 A          0     0            0
10 A          9     5            9
11 B          4     3            4
12 B          0     0            0
13 B          0     6            6
14 B          0     0            0
15 B         18     2            1
16 B          1     4            6
17 B          1     5           18
18 B          0     0            0
19 B          3     2            1
20 B          6     1            6

我真的不明白这是怎么回事,但这并没有给我我想要的. 我也try 了case_when 功能,但我不能很好地使用它,因为它不断抛出错误,LHS和RHS不匹配.

有谁能给我指个方向吗?

(我使用的是R 4.3.2.和dplyr版本1.1.2)

推荐答案

您应该使用replace来仅填充非0值的向量.

library(dplyr)
df %>% 
  group_by(group) %>%
  mutate(column_wanted = replace(index, index != 0, rev(sort(value[value != 0]))[index[index != 0]]))

#    group value index column_wanted
# 1      A     0     0             0
# 2      A     0     4             8
# 3      A    11     3             9
# 4      A     5     3             9
# 5      A     9     2             9
# 6      A     8     6             5
# 7      A     0     0             0
# 8      A     6     1            11
# 9      A     0     0             0
# 10     A     9     5             6
# 11     B     4     3             4
# 12     B     0     0             0
# 13     B     0     6             1
# 14     B     0     0             0
# 15     B    18     2             6
# 16     B     1     4             3
# 17     B     1     5             1
# 18     B     0     0             0
# 19     B     3     2             6
# 20     B     6     1            18

Explanation

ifelsereplace略有不同,因为它使用的是原始向量大小(index)而不是新的向量大小(index[index != 0]).如果尺寸太短,它就会回收.

如果判断第一组的值:

with(df[df$group == "A",], rev(sort(value[value != 0]))[index[index != 0]], 0)
#[1]  8  9  9  9  5 11  6

ifelse所做的是创建一个大小为index的向量,当index为0时使用0,如果不是,则使用大于0的值,但它不会将值102.

# sorted values to match group size (recycled)
#[1]  8  9  9  9  5 11  6  8  9  9

# with 0s (output of ifelse)
#[1]  0  9  9  9  5 11  0  8  0  9

# correct output (replace)
#[1]  0  8  9  9  9  5  0 11  0  6

R相关问答推荐

r中的stat_difference函数不起作用

R箱形图gplot 2 4组但6个参数

将复杂的组合列表转换为数据框架

从gtsummary包中使用tBL_strata()和tBL_summary()时删除变量标签

带有叠加饼图系列的Highmap

矩阵%*%矩阵中的错误:需要数字/复杂矩阵/向量参数

在GGPLATE中将突出的点放在前面

以更少间隔的较小表中的聚合离散频率表

2个Rscript.exe可执行文件有什么区别?

您是否可以使用facet_rap设置一个较低的限制来对ggmap上的比例中断进行zoom ?

如何使这些react 表对象相互独立?

为什么这个表格格罗布不打印?

如何提取R中其他字符串和数字之间的字符串?

使用ifElse语句在ggploy中设置aes y值

整理曲线图、曲线图和点图

根据排名的顶点属性调整曲线图布局(&Q)

网络抓取NBA.com

通过匹配另一个表(查找表)中的列值来填充数据表,并在另一个变量上进行内插

如何捕获这个shiny 的、可扩展的react 性用户输入矩阵作为另一个react 性对象,以便进一步操作?

创建由三个单独的shapefile组成的单个 map