R:未知列数的行的最小值和最大值

R:未知列数的行的最小值和最大值,r,dplyr,R,Dplyr,对于数据帧,我需要按行查找第2列之后未知列数的最小值和最大值。以下是一个例子: library(tidyverse) # test data (test_data <- tibble(id = c(1:9), x = runif(9), x2 = runif(9), x3 = runif(9))) samples = 100 # This examp

对于数据帧,我需要按行查找第2列之后未知列数的最小值和最大值。以下是一个例子:

library(tidyverse)

# test data
(test_data <- tibble(id = c(1:9), 
                     x = runif(9), 
                     x2 = runif(9),
                     x3 = runif(9)))
samples = 100    

# This example, which specifies the column names, correctly finds the min and max values by row
(test_1 <- test_data %>% 
  rowwise() %>%
  mutate(min_val = min(x, x2, x3), max_val = max(x, x2, x3)))

# This example does not
(test_2 <- test_data %>% 
    rowwise() %>%
    mutate(min_val = min(x:x3), max_val = max(x:x3)))
因为(1)我希望保留id列(以便以后与另一个数据帧连接),以及(2)按列位置指定似乎是一种明显的方法,因为我不关心列名,而且样本可能很大

谢谢大家!

编辑的示例

这(如建议的那样)

处理原始测试数据。然而,真实世界的数据有重复的id,例如

(test_data <- tibble(id = c(1:9, 1:9), 
                     x = runif(18), 
                     x2 = runif(18),
                     x3 = runif(18)))

(test_data一个可能的
tidyverse
解决方案是
嵌套
除了
id
之外的所有列,然后使用
map
获得
min
max
。您不需要指定任何列名:

library(tidyverse)

# test data
(test_data <- tibble(id = c(1:9), 
                     x = runif(9), 
                     x2 = runif(9),
                     x3 = runif(9)))
samples = 100    

test_data %>%
  nest(-id) %>%                         # nest rest of columns apart from id
  mutate(min_val = map(data, min),      # get min and max
         max_val = map(data, max)) %>%
  unnest()                              # unnest columns

# # A tibble: 9 x 6
#      id min_val max_val      x     x2    x3
#   <int>   <dbl>   <dbl>  <dbl>  <dbl> <dbl>
# 1     1  0.0217   0.239 0.130  0.0217 0.239
# 2     2  0.125    0.814 0.625  0.814  0.125
# 3     3  0.281    0.770 0.331  0.770  0.281
# 4     4  0.123    0.868 0.123  0.644  0.868
# 5     5  0.149    0.340 0.149  0.340  0.337
# 6     6  0.496    0.865 0.596  0.865  0.496
# 7     7  0.0766   0.984 0.0766 0.656  0.984
# 8     8  0.272    0.926 0.702  0.926  0.272
# 9     9  0.433    0.912 0.912  0.433  0.590

这里有一个选项带有
pmin/pmax

library(tidyverse)
test_data %>% 
     mutate(min_val = pmin(!!! rlang::syms(names(.)[-1])),
            max_val = pmax(!!! rlang::syms(names(.)[-1])))
# A tibble: 9 x 6
#     id     x     x2     x3 min_val max_val
#  <int> <dbl>  <dbl>  <dbl>   <dbl>   <dbl>
#1     1 0.293 0.255  0.501   0.255    0.501
#2     2 0.225 0.605  0.139   0.139    0.605
#3     3 0.704 0.371  0.0939  0.0939   0.704
#4     4 0.519 0.672  0.552   0.519    0.672
#5     5 0.663 0.673  0.725   0.663    0.725
#6     6 0.920 0.320  0.138   0.138    0.920
#7     7 0.280 0.904  0.223   0.223    0.904
#8     8 0.764 0.198  0.688   0.198    0.764
#9     9 0.802 0.0442 0.0765  0.0442   0.802
库(tidyverse)
测试数据%>%
变异(min_val=pmin(!!!rlang::syms(name(.)[-1])),
max_val=pmax(!!!rlang::syms(名称(.)[-1]))
#一个tibble:9x6
#内径x x2 x3最小值最大值
#             
#1     1 0.293 0.255  0.501   0.255    0.501
#2     2 0.225 0.605  0.139   0.139    0.605
#3     3 0.704 0.371  0.0939  0.0939   0.704
#4     4 0.519 0.672  0.552   0.519    0.672
#5     5 0.663 0.673  0.725   0.663    0.725
#6     6 0.920 0.320  0.138   0.138    0.920
#7     7 0.280 0.904  0.223   0.223    0.904
#8     8 0.764 0.198  0.688   0.198    0.764
#9     9 0.802 0.0442 0.0765  0.0442   0.802
数据
set.seed(24)

test\u data Note,您不需要调用
group\u by()
。只需使用
nest(-id)
即可。谢谢。我已经习惯了
group\u by
nest
,但从现在开始,我将改变这一点:)而不是因为您不仅回答了这个问题,还因为我向我展示了在这种情况下如何使用map(我一直试图用它来获得行方式的最小值和最大值,觉得这是一种更好的方法,但没有成功)。此示例在测试日非常有效。但是,在我的真实数据集上,我收到“错误:所有嵌套列必须具有相同数量的元素”。这似乎是因为id列具有重复的id值(我已适当地编辑了原始问题)。谢谢你可以通过
df为所有行分配一个唯一的ID。我已经更新了我的答案。我正在使用
row\u number
创建一个唯一的ID,但是
rowid\u to\u column
也很好。谢谢你:这样做了。ID=c(1:9,1\u 9)也可以实现这个功能,即使用重复的id变量,这是我所需要的!它还可以处理我的实际数据(>100000行)。但是,我承认,我不理解语法“min_val=pmin(!!!rlang::syms(names(.)[-1])!@Martino the
names(.)[-1]
以字符串形式给出数据集的列名,第一个列名除外。它用
syms
转换为
symbol
,然后求值(
!!!
)以获得那些列的值,其中
pmin
pmax
应用了行最小值或最大值。感谢您的解释(我至少部分理解!)-我将进一步研究这一点。
library(tidyverse)

# test data
(test_data <- tibble(id = c(1:9), 
                     x = runif(9), 
                     x2 = runif(9),
                     x3 = runif(9)))
samples = 100    

test_data %>%
  nest(-id) %>%                         # nest rest of columns apart from id
  mutate(min_val = map(data, min),      # get min and max
         max_val = map(data, max)) %>%
  unnest()                              # unnest columns

# # A tibble: 9 x 6
#      id min_val max_val      x     x2    x3
#   <int>   <dbl>   <dbl>  <dbl>  <dbl> <dbl>
# 1     1  0.0217   0.239 0.130  0.0217 0.239
# 2     2  0.125    0.814 0.625  0.814  0.125
# 3     3  0.281    0.770 0.331  0.770  0.281
# 4     4  0.123    0.868 0.123  0.644  0.868
# 5     5  0.149    0.340 0.149  0.340  0.337
# 6     6  0.496    0.865 0.596  0.865  0.496
# 7     7  0.0766   0.984 0.0766 0.656  0.984
# 8     8  0.272    0.926 0.702  0.926  0.272
# 9     9  0.433    0.912 0.912  0.433  0.590
test_data %>%
  mutate(row_id = row_number()) %>%     # create a row identifier
  nest(-id, -row_id) %>%                # nest rest of columns apart from id and row id
  mutate(min_val = map(data, min),      # get min and max
         max_val = map(data, max)) %>%
  unnest()                              # unnest columns
library(tidyverse)
test_data %>% 
     mutate(min_val = pmin(!!! rlang::syms(names(.)[-1])),
            max_val = pmax(!!! rlang::syms(names(.)[-1])))
# A tibble: 9 x 6
#     id     x     x2     x3 min_val max_val
#  <int> <dbl>  <dbl>  <dbl>   <dbl>   <dbl>
#1     1 0.293 0.255  0.501   0.255    0.501
#2     2 0.225 0.605  0.139   0.139    0.605
#3     3 0.704 0.371  0.0939  0.0939   0.704
#4     4 0.519 0.672  0.552   0.519    0.672
#5     5 0.663 0.673  0.725   0.663    0.725
#6     6 0.920 0.320  0.138   0.138    0.920
#7     7 0.280 0.904  0.223   0.223    0.904
#8     8 0.764 0.198  0.688   0.198    0.764
#9     9 0.802 0.0442 0.0765  0.0442   0.802
set.seed(24)
test_data <- tibble(id = c(1:9), 
                    x = runif(9), 
                    x2 = runif(9),
                    x3 = runif(9))