我有一个包含3列的data.frame。第三列有数字或字符类型“1:5”,“30:20”,“1:10”等。我正在尝试将具有这些字符的值拆分为两个然后在它们之间划分但是我我坚持这个:
datos[,3]=gsub(":", " ", datos[,3])
if (datos[,1]==TRUE)
{
s=datos[,3]
chr.pos <- which(unlist(strsplit(s,NULL)) == " ")
chr.count <- length(chr.pos)
one=as.numeric(substr(s,1,chr.pos-1))
two=as.numeric(substr(s,chr.pos+1,nchar(as.character(s))))
datos[,3]=round(two/one,5)
}
答案 0 :(得分:3)
如果您可以确定始终有两个以冒号分隔的数字:
,则可以执行以下操作:
x <- c('1:5', '30:20', '1:10')
strsplit(x, ':')
lapply(strsplit(x, ':'), function(v) as.integer(v[1])/as.integer(v[2]))
然后将其分配回您想要的位置。如果是data.frame:
datos[,3] <- unlist(lapply(strsplit(x, ':'), function(v) as.integer(v[1])/as.integer(v[2]))
)
走过那些东西:
strsplit
返回一个向量列表,其中包含您传递的分割字符两侧的内容(我使用:
)。看看它的作用:
str(strsplit(x, ':'))
List of 3
$ : chr [1:2] "1" "5"
$ : chr [1:2] "30" "20"
$ : chr [1:2] "1" "10"
lapply
作用于列表,该列表将您指定的函数应用于列表的每个元素。我定义了一个函数,它将v
的第一个值除以第二个值。但是,我需要将它们强制转换为数字,因为它们来自strsplit
字符串。
最后,lapply
也会返回一个列表。如果您直接将此内容分配给data.frame
的一列,您将会遇到令人不快的惊喜。相反,请使用unlist
将列表更改为向量,并将其分配到data.frame
列。
此外,正如mnel在评论中提到的那样,data.table
是R的一个包,它具有一些很棒的功能,但与基础R数据结构data.frame
的语法大不相同。
答案 1 :(得分:1)
试试这个。注意:添加了'col.names'以禁止对rownames的默认处理。
x=c("1", "2", "3", "2:3","4","5","3:2")
datos <- data.frame(1:7, 1:7, x=x)
newframe <- cbind( datos[1:2],
read.table(text= as.character(datos[[3]]), sep=":",
fill=TRUE, colClasses="numeric",
col.names=c("V3", "V4")
)
)
> newframe
X1.7 X1.7.1 V3 V4
1 1 1 1 NA
2 2 2 2 NA
3 3 3 3 NA
4 4 4 2 3
5 5 5 4 NA
6 6 6 5 NA
7 7 7 3 2