R 在包含序列的变量名的数据框中分别计算多个变量

R 在包含序列的变量名的数据框中分别计算多个变量,r,dplyr,count,R,Dplyr,Count,我有一个巨大的数据框,它有多个变量名,并遵循一个序列。为了简化,我创建了一个包含8个变量的示例,最后5个变量在列名中按顺序排列: I5min_阈值118,I5min_阈值118.5,I5min_阈值119,I5min_阈值119.5,I5min_阈值120 变量名称中的序列只是一个示例,可以发散,例如,变量序列名称可以是60到180乘以0.1步,在本例中是118到120乘以0.5步 可再现数据框: df<-data.frame(Event=c("yes","yes","yes","no",

我有一个巨大的数据框,它有多个变量名,并遵循一个序列。为了简化,我创建了一个包含8个变量的示例,最后5个变量在列名中按顺序排列: I5min_阈值118,I5min_阈值118.5,I5min_阈值119,I5min_阈值119.5,I5min_阈值120

变量名称中的序列只是一个示例,可以发散,例如,变量序列名称可以是60到180乘以0.1步,在本例中是118到120乘以0.5步

可再现数据框:

df<-data.frame(Event=c("yes","yes","yes","no","no","no","no","no","no"),
           mois=c(0.3,0.2,0.2,0.3,0.3,0.3,0.3,0.3,0.2),
           I_float=c(96.0,100.8,96.0,21.6,10.8,10.8,16.8,8.4,16.8),
           Imax.118=c(95.0,105.0,77.0,15.0,5.0,49.7,53.8,51.2,57.8),
           Imax.118.5=c(97.0,90.0,100.0,16.0,15.0,50.2,54.3,51.7,58.3),
           Imax.119=c(98.0,110.0,78.0,51.4,8.0,50.7,54.8,52.2,58.8),
           Imax.119.5=c(99.8,71.0,80.0,51.9,51.2,51.2,55.3,52.7,59.3),
           Imax.120=c(54.6,71.5,79.0,52.4,51.7,51.7,55.8,53.2,59.8))
以下是数据框的外观:

我希望为每个Imax计算以下变量,并将其存储在新的数据帧中:

如果Event=yes,则I_float>=Imax的次数,作为变量TP。 如果事件=是,则I_float=Imax的次数,作为变量FP。 如果事件=否,I_float 现在我只计算了1个变量的TP、FN、TN和FP,比如说变量Imax.118,方法是在前面示例的r代码Imax.118的第一行中精确地指示变量名。我不能手动使用这个方法,因为在一个名称序列后面的实际数据帧中有数百个变量

任何帮助都将不胜感激。

使用GARGET,我们可以使数据变长,只保留原始Imax列的数字和点,然后在Yintercept列上分组,并对在TP、FN、TN和FP列指定的条件下返回TRUE的行数求和


一种方法是使用pivot_(在最新版本的tidyr中不再可用),将其转换为长格式

然后,使用case_进行比较并确定每行的真/假阳性/阴性

在通过Yintercept和outcome进行总结后,您可以使用pivot_更广泛地创建最终结果

df %>%
  pivot_longer(cols = starts_with("Imax"), names_to = "Yintercept", names_pattern = "^Imax.(\\d.+)",
               names_ptypes = list(Yintercept = double())) %>%
  mutate(outcome = case_when((I_float >= value) & (Event == "yes") ~ "TP",
                             (I_float < value) & (Event == "yes") ~ "FN",
                             (I_float >= value) & (Event == "no") ~ "FP",
                             (I_float < value) & (Event == "no") ~ "TN")) %>%
  group_by(Yintercept, outcome) %>%
  summarise(count = n()) %>%
  pivot_wider(id_cols = Yintercept, names_from = "outcome", values_from = "count", values_fill = list(count = 0))
输出


非常感谢您的快速回复,我正在努力解决这个问题……欢迎您。顺便说一下,你可以考虑把一个答案标记为“接受”。然后所有其他用户都知道这个问题已经得到了充分的回答。另请参见:Hi@Lennyy,现在我试图从更复杂的变量名中提取字符串。在我使用Imax.n之前,其中n是一个数字,我们在结果数据框中称为Yintercept。现在我正在使用变量模式I5min\u thresh\u m\n,例如I5min\u thresh\u-140\u 80。如果我创建一个字符变量string,我不明白我在语法上犯了什么错误。此外,是否可以提取m和n值并将其作为两个变量m和n存储在结果数据框中?对于Imax_thresh_u-140_80,期望结果为m=-140和n=80,然后是总结值TP、FN、TN、FP?。感谢@LennyyI尝试以gsub^?:[^33;]+{2}.+?,、字符串的形式编写gsub函数,结果是140_80和no-140_80。无论如何,当我替换gsubImax\\\、Yintercept for gsub^?:[^ _]+{2}.+?、Yintercept时,结果是相同的,只有1个观测值具有Yintercept值NA,以及强制警告Hanks引入的NAs!是否可以在Yintercept的输出中替换Imax?@RaülOo Yes,更改为Yintercept-请参阅编辑的答案。感谢您提供的代码,我将保存这两个答案以备将来使用。
df %>%
  pivot_longer(cols = starts_with("Imax"), names_to = "Yintercept", names_pattern = "^Imax.(\\d.+)",
               names_ptypes = list(Yintercept = double())) %>%
  mutate(outcome = case_when((I_float >= value) & (Event == "yes") ~ "TP",
                             (I_float < value) & (Event == "yes") ~ "FN",
                             (I_float >= value) & (Event == "no") ~ "FP",
                             (I_float < value) & (Event == "no") ~ "TN")) %>%
  group_by(Yintercept, outcome) %>%
  summarise(count = n()) %>%
  pivot_wider(id_cols = Yintercept, names_from = "outcome", values_from = "count", values_fill = list(count = 0))
# A tibble: 5 x 5
# Groups:   Yintercept [5]
  Yintercept    FN    FP    TN    TP
       <dbl> <int> <int> <int> <int>
1      118       1     2     4     2
2      118.5     2     1     5     1
3      119       2     1     5     1
4      119.5     1     0     6     2
5      120       0     0     6     3