0

我有一个包含 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)
    }
4

2 回答 2

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第二个的函数。但是,我需要将它们强制转换为数字,因为它们来自strsplitas 字符串。

最后,lapply还返回一个列表。如果您将其直接分配给您的列,您data.frame会感到不快。相反,使用unlist将列表更改为向量并将其分配给您的data.frame列。

此外,正如评论中提到的 mnel ,data.table它是一个 R 包,它具有一些出色的功能,但与基本 R 数据结构有很大不同的语法data.frame

于 2012-12-17T23:25:11.863 回答
1

试试这个。注意:添加了“col.names”以禁止默认处理行名。

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
于 2012-12-17T23:53:36.350 回答