String 用R识别复杂字符串中的多个id
我有一个数据帧,有很多字符串和这样的值String 用R识别复杂字符串中的多个id,string,r,String,R,我有一个数据帧,有很多字符串和这样的值 ID String Value 1 LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32 100 2 LocationID=123,345&TimeID=456,321 50 3 LocationID=123,321,
ID String Value
1 LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32 100
2 LocationID=123,345&TimeID=456,321 50
3 LocationID=123,321,345&TypeID=32 120
...
正如您在示例中看到的,“,”表示“或”。因此locationID=123321345指的是那些具有位置ID 123、321或345的元素。“值”可以被认为是满足字符串的条目数
我想编写一个程序,用R计算每个ID的出现次数。也就是说,程序的输出应该是:
ID Occurrence
LocationID = 123 270 #(100+50+120)
LocationID = 321 220 #(100+120)
...
TypeID = 12 100
...
有谁能给我一些关于如何做这项工作的建议吗
我发现很难处理“,”和ID。否则我可以使用for循环,尽管我讨厌for循环
还有一个问题,ID应该允许空字符或字符,如下所示:
ID String Value
1 LocationID=123,321,345&TimeID=456,321,789&TypeID= 100
2 LocationID=123,345&TimeID=&TypeID=A 50
3 LocationID=123,321,345&TypeID=32 120
temp2
# ID Measure Param Value
# 1 1 123 LocationID 100
# 2 1 321 LocationID 100
# 3 1 345 LocationID 100
# 4 1 456 TimeID 100
# 5 1 321 TimeID 100
# 6 1 789 TimeID 100
# 7 1 12 TypeID 100
# 8 1 32 TypeID 100
# 9 2 123 LocationID 50
# 10 2 345 LocationID 50
# 11 2 456 TimeID 50
# 12 2 321 TimeID 50
# 13 3 123 LocationID 120
# 14 3 321 LocationID 120
# 15 3 345 LocationID 120
# 16 3 32 TypeID 120
尝试使用strsplit函数,您可以像这样标记字符串
strsplit("LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32","&"); ## this will tokenize by splitting by &;
然后使用grep确定LocationID、TimeID、TypeID的存在,并通过“=”和“,”将值附加到辅助帧中来适当地设置strsplit
最后叫一个“tapply”
希望这有助于概括尝试使用strsplit函数,您可以像这样标记字符串
strsplit("LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32","&"); ## this will tokenize by splitting by &;
然后使用grep确定LocationID、TimeID、TypeID的存在,并通过“=”和“,”将值附加到辅助帧中来适当地设置strsplit
最后叫一个“tapply”
希望这有助于概括你可以这样做
dat <- read.table(text = 'ID String Value
1 LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32 100
2 LocationID=123,345&TimeID=456,321 50
3 LocationID=123,321,345&TypeID=32 120',header= T, stringsAsFactors=F)
## split by &
ll <- unlist(strsplit(dat$String,'&'))
## create 2 lits of occuonces and id names
occs <- strsplit(gsub('(.*)ID=(.*)','\\2',ll),',')
ids <- gsub('(.*)ID=(.*)','\\1',ll)
names(occs) <- ids
ll <- sapply(names(occs),function(x) occs[x] <- paste(x,occs[[x]], sep ='_'))
## use rapply to change list in data.frame then count by table
table(rapply(ll,I))
Location_123 Location_321 Location_345 Time_321 Time_456 Time_789 Type_12 Type_32
3 3 3 2 2 2 2 2
dat您可以这样做
dat <- read.table(text = 'ID String Value
1 LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32 100
2 LocationID=123,345&TimeID=456,321 50
3 LocationID=123,321,345&TypeID=32 120',header= T, stringsAsFactors=F)
## split by &
ll <- unlist(strsplit(dat$String,'&'))
## create 2 lits of occuonces and id names
occs <- strsplit(gsub('(.*)ID=(.*)','\\2',ll),',')
ids <- gsub('(.*)ID=(.*)','\\1',ll)
names(occs) <- ids
ll <- sapply(names(occs),function(x) occs[x] <- paste(x,occs[[x]], sep ='_'))
## use rapply to change list in data.frame then count by table
table(rapply(ll,I))
Location_123 Location_321 Location_345 Time_321 Time_456 Time_789 Type_12 Type_32
3 3 3 2 2 2 2 2
dat试试这个lapply2
与lappy
类似,只是它是后面的结果。我们拆分字符串参数并将结果放入s
。然后我们计算一个新的数据帧dat2
,每个ID有一行。对于样本数据,第1行有3个ID,第2行有2个ID,第3行有2个ID,因此dat2
有3+2+2=7行。以类似的方式,我们分解dat2
生成dat3
。作为其中的一部分,我们使用Straplyc
来简化提取所有事件的过程。最后,我们使用aggregate
来计算结果
library(gsubfn)
lapply2 <- function(...) do.call("rbind", lapply(...))
s <- strsplit(dat$String, "&")
dat2 <- lapply2(1:nrow(dat), function(i)
data.frame(
String = I(s[[i]]),
Value = dat$Value[i]
)
)
dat3 <- lapply2(1:nrow(dat2), function(i)
data.frame(
String = sub("=.*", "", dat2$String[i]),
Occurrence = strapplyc(dat2$String[i], "\\d+")[[1]],
Value = dat2$Value[i]
)
)
ag <- aggregate(Value ~ String + Occurrence, dat3, sum)
试试这个lapply2
与lappy
类似,只是它是后面的结果。我们拆分字符串参数并将结果放入s
。然后我们计算一个新的数据帧dat2
,每个ID有一行。对于样本数据,第1行有3个ID,第2行有2个ID,第3行有2个ID,因此dat2
有3+2+2=7行。以类似的方式,我们分解dat2
生成dat3
。作为其中的一部分,我们使用Straplyc
来简化提取所有事件的过程。最后,我们使用aggregate
来计算结果
library(gsubfn)
lapply2 <- function(...) do.call("rbind", lapply(...))
s <- strsplit(dat$String, "&")
dat2 <- lapply2(1:nrow(dat), function(i)
data.frame(
String = I(s[[i]]),
Value = dat$Value[i]
)
)
dat3 <- lapply2(1:nrow(dat2), function(i)
data.frame(
String = sub("=.*", "", dat2$String[i]),
Occurrence = strapplyc(dat2$String[i], "\\d+")[[1]],
Value = dat2$Value[i]
)
)
ag <- aggregate(Value ~ String + Occurrence, dat3, sum)
格罗森迪克的答案要好得多,但因为我已经开始研究解决方案,所以答案就在这里。这会粘在底端R上,并涉及一个长的lappy
。假设您的数据名为“mydata”:
首先,用符号AND拆分“String”列
temp1 <- strsplit(mydata$String, "&")
结果如下所示:
ID String Value
1 LocationID=123,321,345&TimeID=456,321,789&TypeID= 100
2 LocationID=123,345&TimeID=&TypeID=A 50
3 LocationID=123,321,345&TypeID=32 120
temp2
# ID Measure Param Value
# 1 1 123 LocationID 100
# 2 1 321 LocationID 100
# 3 1 345 LocationID 100
# 4 1 456 TimeID 100
# 5 1 321 TimeID 100
# 6 1 789 TimeID 100
# 7 1 12 TypeID 100
# 8 1 32 TypeID 100
# 9 2 123 LocationID 50
# 10 2 345 LocationID 50
# 11 2 456 TimeID 50
# 12 2 321 TimeID 50
# 13 3 123 LocationID 120
# 14 3 321 LocationID 120
# 15 3 345 LocationID 120
# 16 3 32 TypeID 120
因此,现在我们可以很容易地在输出上使用aggregate
,以获得以下结果:
aggregate(Value ~ Param + Measure, temp2, sum)
# Param Measure Value
# 1 TypeID 12 100
# 2 TypeID 32 220
# 3 LocationID 123 270
# 4 LocationID 321 220
# 5 TimeID 321 150
# 6 LocationID 345 270
# 7 TimeID 456 150
# 8 TimeID 789 100
为方便起见,以下是数据前几行的dput
:
mydata <- structure(list(ID = 1:3,
String = c("LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32",
"LocationID=123,345&TimeID=456,321",
"LocationID=123,321,345&TypeID=32"),
Value = c(100L, 50L, 120L)),
.Names = c("ID", "String", "Value"),
row.names = c(NA, -3L),
class = "data.frame")
mydataG.Grothendieck的答案要好得多,但既然我已经开始研究一个解决方案,就在这里。这会粘在底端R上,并涉及一个长的lappy
。假设您的数据名为“mydata”:
首先,用符号AND拆分“String”列
temp1 <- strsplit(mydata$String, "&")
结果如下所示:
ID String Value
1 LocationID=123,321,345&TimeID=456,321,789&TypeID= 100
2 LocationID=123,345&TimeID=&TypeID=A 50
3 LocationID=123,321,345&TypeID=32 120
temp2
# ID Measure Param Value
# 1 1 123 LocationID 100
# 2 1 321 LocationID 100
# 3 1 345 LocationID 100
# 4 1 456 TimeID 100
# 5 1 321 TimeID 100
# 6 1 789 TimeID 100
# 7 1 12 TypeID 100
# 8 1 32 TypeID 100
# 9 2 123 LocationID 50
# 10 2 345 LocationID 50
# 11 2 456 TimeID 50
# 12 2 321 TimeID 50
# 13 3 123 LocationID 120
# 14 3 321 LocationID 120
# 15 3 345 LocationID 120
# 16 3 32 TypeID 120
因此,现在我们可以很容易地在输出上使用aggregate
,以获得以下结果:
aggregate(Value ~ Param + Measure, temp2, sum)
# Param Measure Value
# 1 TypeID 12 100
# 2 TypeID 32 220
# 3 LocationID 123 270
# 4 LocationID 321 220
# 5 TimeID 321 150
# 6 LocationID 345 270
# 7 TimeID 456 150
# 8 TimeID 789 100
为方便起见,以下是数据前几行的dput
:
mydata <- structure(list(ID = 1:3,
String = c("LocationID=123,321,345&TimeID=456,321,789&TypeID=12,32",
"LocationID=123,345&TimeID=456,321",
"LocationID=123,321,345&TypeID=32"),
Value = c(100L, 50L, 120L)),
.Names = c("ID", "String", "Value"),
row.names = c(NA, -3L),
class = "data.frame")
mydata非常感谢您,但是如果数据允许这种格式,您能进一步给我一些建议吗?ID字符串值1 LocationID=123321345&TimeID=456321789&TypeID=100 2 LocationID=123345&TimeID=&TypeID=a 50 3 LocationID=123321345&TypeID=32 120这是ID可以是字符串也可以是空的dat2$String
对于空的右侧,将以=
结尾,因此只需删除这些行:dat2非常感谢,但是如果数据允许这种格式,您能进一步给我一些建议吗?ID字符串值1 LocationID=123321345&TimeID=456321789&TypeID=100 2 LocationID=123345&TimeID=&TypeID=a 50 3 LocationID=123321345&TypeID=32 120这是ID可以是字符串也可以是空的dat2$String
对于空的右侧,将以=
结尾,因此只需删除这些行:dat2非常感谢!最后,我使用了您的建议,因为它更容易修改以解决我进一步的数据需求,再次感谢!谢谢!最后,我使用了您的建议,因为它更容易修改以解决我进一步的数据需求,再次感谢!