【问题标题】:split values and then operate with them using R拆分值,然后使用 R 对它们进行操作
【发布时间】:2012-12-17 23:19:51
【问题描述】:

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

【问题讨论】:

  • 当你说data.table时,你是指data.table还是只是data.frame
  • 谢谢 我的意思是我使用了 read.csv 指令,但老实说我不太清楚两者之间的区别。
  • 如果您使用 read.csv,那么您就有一个“数据框”。请更仔细地研究您的介绍性材料。
  • 谢谢你是对的。由于第三列包含数字数据与这些字符串与列“混合”,因此我很难找到适用于两者的正确命令。
  • 您的第三列不能包含“混合”数据。 data.frames 的列只能是一种类型。但是,如果您有一些行是字符串 1 ("1"),而其他行是字符串 "1:5",您希望如何处理这些情况?

标签: r


【解决方案1】:

如果您可以确定始终有两个数字用冒号分隔,: 您可以执行以下操作:

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 的语法大不相同。

【讨论】:

  • 非常感谢您的帮助和解释。使用 strsplit(x, ":") 时出现错误。我认为这是因为我读取的文件在同一列中包含其他数据类型(没有任何冒号)。错误是参数类型非字符。
  • 您可以使用str 查看您的数据。但是,该错误告诉您要发送到 strsplit 的列不是字符类型(它可能是数字!)。
  • @user1228124 将str(datos)dput(head(datos)) 的输出添加到您的问题中将有助于了解发生了什么。
  • 这给了我更多的信息。第三个变量/列是 $ V3: Factor.
  • 因素很棒,但当您不知道它们的存在时,它们会给您带来令人惊讶的结果。查看?factor 以获取有关从因子转换回字符或数字的更多信息。
【解决方案2】:

试试这个。注意:添加了“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

【讨论】:

  • 感谢代码,我收到以下错误: textConnection(text) 参数中的错误无效。我相信这可能是因为同一列中的两种数据类型。
  • 已修复。由于 stringsAsFactors 的默认 R 设置,是一个因子变量。
  • 谢谢。我发现的问题是,在您的示例中,x 向量总是有一个冒号,而我的 x 向量类似于这个 x=c(1, 2, 3, "2:3",4,5,"3:2") .我已经更改了 data.frame,所以如果第 3 列有冒号,我在第一列中有 TRUE,如果没有,我有 FALSE。有没有办法让如果第 1 列为 TRUE 然后拆分字符串,将拆分字符串的两边都转换为数字并将它们分开,这样我最终只有一个数字?我也在尝试循环,但不起作用。
  • 你的描述我不清楚。尝试在您的示例中发布 dput() 并发布在答案正文而不是 cmets 中。
  • 很好的解决方案。我已将其作为one of several options 添加到一个非常相似的问题中。如何合并问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多