Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.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_Dplyr_Melt - Fatal编程技术网

R 基于现有列及其旁边的列的新列

R 基于现有列及其旁边的列的新列,r,dplyr,melt,R,Dplyr,Melt,我的数据框看起来像这样 ID t1 obs1 t2 obs2 t3 obs3 1 0 a 11 d 0 g 2 0 b 13 e 11 i 3 0 c 0 f 0 h 我需要确保每个ID至少有一个大于10的t(如果不是,请删除行)。然后,我想保存10以上的最低t值,但也要将相应的obs保存在新列中。(关于我的问题,最复杂的部分是,10以上的最低t可能在任何列中)。与某个t对应的obs位于下一列中,因此这会有所帮助。因此,我的结果数据框如下所

我的数据框看起来像这样

ID t1 obs1 t2 obs2 t3 obs3
1  0  a    11 d    0  g
2  0  b    13 e    11 i
3  0  c    0  f    0  h
我需要确保每个ID至少有一个大于10的t(如果不是,请删除行)。然后,我想保存10以上的最低t值,但也要将相应的obs保存在新列中。(关于我的问题,最复杂的部分是,10以上的最低t可能在任何列中)。与某个t对应的obs位于下一列中,因此这会有所帮助。因此,我的结果数据框如下所示:

ID t1 obs1 t2 obs2 t3 obs3 lowesttabove10 correspondingobs
1  0  a    11 d    0  g    11             d
2  0  b    13 e    11 i    11             i

我的方法不是很好,但仍然有效,你可以试试

library(dplyr)
library(reshape)
df1=melt(df,id='ID')

df2=df1%>%group_by(ID)%>%filter(value>10)%>%dplyr::slice(which.min(value))%>%na.omit()

> df2
# A tibble: 2 x 3
# Groups:   ID [2]
     ID variable value
  <int>   <fctr> <chr>
1     1       t2    11
2     2       t3    11


df2$variable=as.character(df2$variable)
C=as.numeric(gsub("[[:alpha:]]", "", df2$variable))
df=df[df$ID%in%df2$ID,]
for (i in 1:length(C)){
DF1=df[i,str_detect(names(df),as.character(C[i]))]
names(DF1)=c('lowesttabove10 ','correspondingobs')
if (i ==1 ){DFF=DF1}else{DFF=rbind(DFF,DF1)}
}
cbind(df,DFF)

  ID t1 obs1 t2 obs2 t3 obs3 lowesttabove10  correspondingobs
1  1  0    a 11    d  0    g              11                d
2  2  0    b 13    e 11    i              11                i
库(dplyr)
图书馆(重塑)
df1=熔体(df,id='id')
df2=df1%%>%group_by(ID)%%>%filter(value>10)%%>%dplyr::slice(which.min(value))%%>%na.omit()
>df2
#一个tibble:2x3
#组别:ID[2]
ID变量值
1 1 t2 11
2 t3 11
df2$variable=as.character(df2$variable)
C=as.numeric(gsub(“[:alpha:][]”,“”,df2$变量))
df=df[df$ID%在%df2$ID中,]
适用于(i/1:长度(C)){
DF1=df[i,str_detect(名称(df),as.character(C[i]))
名称(DF1)=c('lowersttabove10','correspondingobs')
如果(i==1){DFF=DF1}否则{DFF=rbind(DFF,DF1)}
}
cbind(df,DFF)
ID t1 obs1 t2 obs2 t3 obs3下表10对应的obs2
11A11D 0G11D
2 2 0 b 13 e 11 i 11 i

解决方案在一个管道中使用
dplyr
tidyr
dt
是原始数据,
dt2
是最终输出

library(dplyr)
library(tidyr)

dt2 <- dt %>%
  gather(t_group, t_value, starts_with("t")) %>%
  gather(obs_group, obs_value, starts_with("obs")) %>%
  filter(gsub("t", "", t_group) == gsub("obs", "", obs_group)) %>%
  filter(t_value >= 10) %>%
  filter(t_value == min(t_value)) %>%
  select(ID, lowesttabove10 = t_value, correspondingobs = obs_value) %>%
  inner_join(dt, by = "ID") %>%
  select(colnames(dt), lowesttabove10, correspondingobs)

df2
  ID t1 obs1 t2 obs2 t3 obs3 lowesttabove10 correspondingobs
1  1  0    a 11    d  0    g             11                d
2  2  0    b 13    e 11    i             11                i
库(dplyr)
图书馆(tidyr)
dt2%
聚集(t_组,t_值,以(“t”)开头)%>%
聚集(obs_组,obs_值,以(“obs”)开头)%>%
过滤器(gsub(“t”),t_组)==gsub(“obs”,“obs”,obs_组))%>%
过滤器(t_值>=10)%>%
过滤器(t_值==最小值(t_值))%>%
选择(ID,最下选项卡10=t_值,对应的BS=obs_值)%>%
内部联接(dt,by=“ID”)%>%
选择(列名称(dt)、最下表10、对应的选项卡)
df2
ID t1 obs1 t2 obs2 t3 obs3下表10对应的obs2
11A11D 0G11D
2 2 0 b 13 e 11 i 11 i
数据:

dt使用基数R:

删除t值不超过10的所有行:

df1 <- df1[rowSums(df1[, grepl("^t", colnames(df1))] >10) > 0, ]
df1 10)>0,]
确定包含10以上最低值的组,然后检索值:

df1$group <- apply(df1[grepl("^t", names(df1))], 1, function(x) which(x == min(x[x > 10])))
df1 <- cbind(df1, do.call(rbind, lapply(seq_len(nrow(df1)), 
                                        function(x) setNames(df1[x, paste0(c("t", "obs"), df1$group[x])],
                                                             c("lowesttabove10", "correspondingobs")))))

> df1
  ID t1 obs1 t2 obs2 t3 obs3 group lowesttabove10 correspondingobs
1  1  0    a 11    d  0    g     2             11                d
2  2  0    b 13    e 11    i     3             11                i
df1$group 10]))
df1 df1
ID t1 obs1 t2 obs2 t3 obs3 obs3组最下面的10个对应OBS
11A11D0G211D
2 2 0 b 13 e 11 i 3 11 i

对于data.table,转到长格式:

library(data.table)
setDT(DT)
dat = melt(DT, measure.vars = patterns("^t\\d+$", "^obs\\d+$"), value.name = c("t", "obs"))
setorder(dat, ID, variable)

#    ID variable  t obs
# 1:  1        1  0   a
# 2:  1        2 11   d
# 3:  1        3  0   g
# 4:  2        1  0   b
# 5:  2        2 13   e
# 6:  2        3 11   i
# 7:  3        1  0   c
# 8:  3        2  0   f
# 9:  3        3  0   h
查找每个组的最大值并标记要保留的组:

IDDT = dat[order(-t), 
  .(max.variable = first(variable), max.t = first(t), max.obs = first(obs))
, by=ID]
IDDT[, keep := max.t > 10]

#    ID max.variable max.t max.obs  keep
# 1:  2            2    13       e  TRUE
# 2:  1            2    11       d  TRUE
# 3:  3            1     0       c FALSE
使用滚动更新联接查找每个保留组超过10的最小值:

IDDT[(keep), c("my.variable", "my.t", "my.obs") := {
  m = .(ID = ID, t_thresh = 10)
  dat[m, on=.(ID, t = t_thresh), roll=-Inf, .(x.variable, x.t, x.obs)]
}]

#    ID max.variable max.t max.obs  keep my.variable my.t my.obs
# 1:  2            2    13       e  TRUE           3   11      i
# 2:  1            2    11       d  TRUE           2   11      d
# 3:  3            1     0       c FALSE          NA   NA     NA
我就到此为止,主要数据是长格式的
dat
,而
ID
级别变量则在单独的表
IDDT
中。要将
dat
筛选到应保留的组:
dat[IDDT[(保留),(ID)],on=(ID)]
。有关语法的详细信息,请参阅
?data.table
和加载软件包时提到的其他介绍材料


如果您坚持要返回到广域,请参见
?dcast

重塑是为了更好地使用plyr而构建的,而tidyr是为了dplyr,仅供参考。刚刚注意:您需要将df1$值转换为数字。使用character,您将在过滤器内看到
“2”>10
。另外,看起来您的第二步应该/可能是
left_-join(df2,df)
?@Frank是的,您是对的,我这边的
'1'>10
返回
FALSE
您知道我为什么会出现此错误吗?错误:is_DictionarySh(x)不正确不确定。尝试获取最新的
dplyr
tidyverse
软件包。如果错误仍然发生,您可以使用base R或
data.table
中的方法,如其他人建议的那样。
IDDT[(keep), c("my.variable", "my.t", "my.obs") := {
  m = .(ID = ID, t_thresh = 10)
  dat[m, on=.(ID, t = t_thresh), roll=-Inf, .(x.variable, x.t, x.obs)]
}]

#    ID max.variable max.t max.obs  keep my.variable my.t my.obs
# 1:  2            2    13       e  TRUE           3   11      i
# 2:  1            2    11       d  TRUE           2   11      d
# 3:  3            1     0       c FALSE          NA   NA     NA