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

在R中查找相似列名的间隔

在R中查找相似列名的间隔,r,dataframe,intervals,R,Dataframe,Intervals,我想要一个更简单的方法来确定一个值是否在给定的区间内。给定数据帧: Value start1 start2 start3 end1 end2 end3 212 82 195 409 97 220 411 80 57 95 111 69 100 130 如果“Value”在任何间隔([start1-end1]、[start2-end2]等)中,我想用1创建一个新列,如果不是,则用0创建一个新列;因

我想要一个更简单的方法来确定一个值是否在给定的区间内。给定数据帧:

Value  start1  start2  start3  end1  end2  end3
212    82      195     409     97    220   411
80     57      95      111     69    100   130
如果“Value”在任何间隔([start1-end1]、[start2-end2]等)中,我想用1创建一个新列,如果不是,则用0创建一个新列;因此,在上述情况下,第一行的值为1,因为212落在第二个间隔中,第二行的值为0。请注意,这些是当前列的顺序,边缘情况(与间隔的开始或结束匹配的值)应编码为1


我可以用ifelse语句来实现这一点,但是有260列,我觉得这个解决方案在未来的其他方面可能会很有用

带有
数据。表
包:

library(data.table)

dt = data.table(Value=c(212,80), start1=c(82,57), start2=c(195,95), start3=c(409,111),
                end1=c(97,69), end2=c(220,100), end3=c(411,130))

dt[, rowid:= .I]
使用“融化”的桌子更自然:

dt_melt = melt(dt, id=c('rowid','Value'), measure=patterns('start','end'),
               variable.name='interval', value.name=c('start','end'))

#    rowid Value interval start end
# 1:     1   212        1    82  97
# 2:     2    80        1    57  69
# 3:     1   212        2   195 220
# 4:     2    80        2    95 100
# 5:     1   212        3   409 411
# 6:     2    80        3   111 130
现在我们可以在rowid上进行计算并与
dt
合并:

dt[dt_melt[, as.integer(any(between(Value, start, end))), by='rowid'], on='rowid']

#    Value start1 start2 start3 end1 end2 end3 rowid V1
# 1:   212     82    195    409   97  220  411     1  1
# 2:    80     57     95    111   69  100  130     2  0

使用
tidyverse
的解决方案。最终输出在
dt3
数据帧的
InRange
列中

# Create example data frame
dt <- read.table(text = "Value  start1  start2  start3  end1  end2  end3
212    82      195     409     97    220   411
                 80     57      95      111     69    100   130",
                 header = TRUE, stringsAsFactors = FALSE)

# Load packages
library(tidyverse)

# Process the data
dt2 <- dt %>% mutate(GroupID = 1:n()) 

dt3 <- dt2 %>%
  gather(StartEnd, Number, -Value, -GroupID) %>%
  mutate(Type = gsub("[0-9]", "", StartEnd),
         ID = gsub("[a-z]", "", StartEnd)) %>%
  select(-StartEnd) %>%
  spread(Type, Number) %>%
  mutate(InRange = ifelse(Value >= start & Value <= end, 1, 0)) %>%
  group_by(GroupID) %>%
  summarise(InRange = max(InRange)) %>%
  right_join(dt2, by = "GroupID")

除了data.table,我还需要什么吗?它说没有叫做“patterns”的函数吗?不,patterns来自data.table。您使用的是什么版本Nevermind,需要从data.frame转换为data.table谢谢,我应该知道如何融化数据lol。这也将解决我的许多其他问题!
# Process the data
dt2 <- dt %>%
  gather(StartEnd, Number, -Value) %>%
  mutate(Type = gsub("[0-9]", "", StartEnd),
         ID = gsub("[a-z]", "", StartEnd)) %>%
  select(-StartEnd) %>%
  spread(Type, Number) %>%
  mutate(InRange = ifelse(Value >= start & Value <= end, 1, 0)) %>%
  group_by(Value) %>%
  summarise(InRange = max(InRange)) %>%
  right_join(dt, by = "Value")