Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 重复行:根据条件选择行并存储重复的值_R_Duplicates - Fatal编程技术网

R 重复行:根据条件选择行并存储重复的值

R 重复行:根据条件选择行并存储重复的值,r,duplicates,R,Duplicates,我正在处理的原始数据集如下所示: df <- data.frame("ID" = c("Alpha", "Alpha", "Alpha", "Alpha", "Beta","Beta", "Beta","Beta" ), "treatment"= LETTERS[seq(from = 1, to = 8)], "Year" = c(1970, 1970, 1980, 1

我正在处理的原始数据集如下所示:

df <- data.frame("ID" = c("Alpha", "Alpha", "Alpha", "Alpha", 
                          "Beta","Beta", "Beta","Beta" ),
                 "treatment"= LETTERS[seq(from = 1, to = 8)],
                 "Year" = c(1970, 1970, 1980, 1990, 1970, 1980, 
                            1980,1990),
                 "Val" = c(0,0,0,1,0,1,0,1),
                 "Val2" = c(0,2.34,1.3,0,0,2.34,3.2,1.3))
逻辑如下:

1) 我希望每个ID/年只有一个obs

2) 我只想在
Val2
类别中保留具有较高值的观察值

3) 我想将删除的行值存储到单独的列中,以跟踪我正在删除的内容
del_treat
del_Val
del_Val2

举例说明。在df中,对Alpha/1970进行了重复观测。我想把这减少到一行。Val2的值为0和2.34,在最终数据帧中,仅保留2.34。但是,治疗A的值在新创建的列
del_treat
del_Val
del_Val2
中报告

我可以根据
Val2``setDT(df)[order(-Val2)][,.SD[1,],by=(ID,Year)]

值,但我想找到一种简洁的方法将删除的结果“存储”到新列中

这里有一个使用
dplyr
的选项。按“ID”、“Year”分组后,创建一个逻辑列(“ind”),检查“Val2”的
max
,使用该逻辑列创建与“Val”相对应的两列,并将“del”作为前缀用于已消除的值,以及不存在的“treatment”,根据“ind”和
取消分组

library(dplyr)
df %>% 
   group_by(ID, Year) %>% 
   mutate(ind = Val2 == max(Val2) & !is.na(Val2)) %>% 
   mutate_at(vars(matches('Val')), 
        list(del = ~ if(any(!ind)) .[!ind] else NA_real_)) %>% 
   mutate(del_treat = if(any(!ind)) treatment[!ind] else NA_character_) %>% 
   filter(ind) %>%
   ungroup %>%
   select(-ind)

这里有一个带有
dplyr
的选项。按“ID”、“Year”分组后,创建一个逻辑列(“ind”),检查“Val2”的
max
,使用该逻辑列创建与“Val”相对应的两列,并将“del”作为前缀用于已消除的值,以及不存在的“treatment”,根据“ind”和
取消分组

library(dplyr)
df %>% 
   group_by(ID, Year) %>% 
   mutate(ind = Val2 == max(Val2) & !is.na(Val2)) %>% 
   mutate_at(vars(matches('Val')), 
        list(del = ~ if(any(!ind)) .[!ind] else NA_real_)) %>% 
   mutate(del_treat = if(any(!ind)) treatment[!ind] else NA_character_) %>% 
   filter(ind) %>%
   ungroup %>%
   select(-ind)

使用data.table,在按
Val2
降序排序后,基于
rowid(ID,Year)
的dcast可以实现除列名之外的其他目的。“_1”列是“keep”列,“_2”列是“del”列

库(data.table)
setDT(df)
setorder(df,ID,年份,-Val2)
每组输出2行

setnames(out, function(x) gsub('(.*)_1', '\\1', x))
setnames(out, function(x) gsub('(.*_\\d+)', 'del_\\1', x))
out
#       ID Year treatment del_treatment_2 Val del_Val_2 Val2 del_Val2_2
# 1: Alpha 1970         B               A   0         0 2.34       0.00
# 2: Alpha 1980         C            <NA>   0        NA 1.30         NA
# 3: Alpha 1990         D            <NA>   1        NA 0.00         NA
# 4:  Beta 1970         E            <NA>   0        NA 0.00         NA
# 5:  Beta 1980         G               F   0         1 3.20       2.34
# 6:  Beta 1990         H            <NA>   1        NA 1.30         NA
setnames(out,函数(x)gsub('(.*)1','\\1',x))
集合名(out,函数(x)gsub(“(.*\\d+”,“del\\1',x))
出来
#ID年治疗日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期
#1:Alpha 1970 B 0 0 2.34 0.00
#2:Alpha 1980 C0 NA 1.30 NA
#3:Alpha 1990 D 1 NA 0.00 NA
#4:Beta 1970 E 0 NA 0.00 NA
#5:Beta 1980 G F 0 1 3.20 2.34
#6:Beta 1990 H1 NA 1.30 NA

使用data.table,在按
Val2
降序后,基于
rowid(ID,Year)
的dcast可以实现除列名之外的其他功能。“_1”列是“keep”列,“_2”列是“del”列

库(data.table)
setDT(df)
setorder(df,ID,年份,-Val2)
每组输出2行

setnames(out, function(x) gsub('(.*)_1', '\\1', x))
setnames(out, function(x) gsub('(.*_\\d+)', 'del_\\1', x))
out
#       ID Year treatment del_treatment_2 Val del_Val_2 Val2 del_Val2_2
# 1: Alpha 1970         B               A   0         0 2.34       0.00
# 2: Alpha 1980         C            <NA>   0        NA 1.30         NA
# 3: Alpha 1990         D            <NA>   1        NA 0.00         NA
# 4:  Beta 1970         E            <NA>   0        NA 0.00         NA
# 5:  Beta 1980         G               F   0         1 3.20       2.34
# 6:  Beta 1990         H            <NA>   1        NA 1.30         NA
setnames(out,函数(x)gsub('(.*)1','\\1',x))
集合名(out,函数(x)gsub(“(.*\\d+”,“del\\1',x))
出来
#ID年治疗日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期日期
#1:Alpha 1970 B 0 0 2.34 0.00
#2:Alpha 1980 C0 NA 1.30 NA
#3:Alpha 1990 D 1 NA 0.00 NA
#4:Beta 1970 E 0 NA 0.00 NA
#5:Beta 1980 G F 0 1 3.20 2.34
#6:Beta 1990 H1 NA 1.30 NA

非常感谢,这非常高效!非常感谢,这是非常有效的!