R逐元素计算,按组

时间:2019-07-16 03:54:34

标签: r string dplyr

我正在尝试按ID组进行计算。想使用dplyr,但不是必需的。在“历史记录”列中,我有一串数字(均相同,长度为36)。我想应用该规则,逐个元素获取最大(max)值,并为每个ID找出新的单一历史记录。 例如,对于ID = 1157,新的单个字符串应为 432400000000000000000000000000000000000000,因为这些是该ID的每个元素的最大值。我想对所有ID(数千个)执行此操作。

     Id                              history
1  1157 101000000000000000000000000000000000
2  1157 000000000000000000000000000000000000
3  1157 432100000000000000000000000000000000
4  1157 321000000000000000000000000000000000
5  1157 000400000000000000000000000000000000
6  1157 432100000000000000000000000000000000
7  1157 211000000000000000000000000000000000
26 1351 000000000000000000000000000000000000
27 1351 000000000000000000000000000000000000
45 1351 000000000000000000000000000000000000
46 1351 000000000000000000000000000000000000
47 1351 000000000000000000000000000000000000
48 1351 000000000000000000000000000000000000
49 1351 000000000000000000000000000000000000
50 1351 000000000000000000000000000000000000
51 1351 000000000000000000000000000000000000
52 1351 000000000000000000000000000000000000
53 1351 000000000000000000000000000000000000
54 1351 000000000000000000000000000000000000
55 1351 000000000000000000000000000000000000

1 个答案:

答案 0 :(得分:1)

我们可以分割每个字符上的每个history值,并创建一个列表列和group_by Id并使用pmax获得每个位置上具有最大值的元素。 / p>

library(dplyr)
library(purrr)

df %>%
  mutate(new_col = map(history, ~strsplit(., "")[[1L]])) %>%
  group_by(Id) %>%
  summarise(temp = paste0(Reduce(pmax, new_col), collapse = ""))

#  Id    temp                                
# <int> <chr>                               
#1 1157  432400000000000000000000000000000000
#2 1351  000000000000000000000000000000000000

strsplit创建一个字符列表,由于我们正在使用map它创建了另一个列表,因此,输出成为嵌套列表,我们通过使用[[1L]]避免了嵌套,因此{{ 1}}是一个字符向量,而不是列表。

strsplit是一个列表列,使用new_col比较组(Reduce)中所有new_col的值,然后选择Id的元素使用max逐个元素地计算值。

这里要注意的另一件事是我们将pmax作为字符向量列表,这意味着1是“ 1”,2是“ 2”,依此类推。理想情况下,new_col应该是用于比较目的的整数向量列表,但在这里我认为这没关系,因为我们正在进行逐元素比较,并且其结果将与普通整数比较相同。测试一些

new_col

在基数R中使用相同的逻辑,这将是

"2" > "1"
#[1] TRUE
"6" < "1"
#[1] FALSE

数据

stack(lapply(split(strsplit(df$history, ""), df$Id), function(x) 
              paste0(Reduce(pmax, x), collapse = "")))

#                                values  ind
#1 432400000000000000000000000000000000 1157
#2 000000000000000000000000000000000000 1351