【问题标题】:manipulating two data frames based on string with different lengths基于不同长度的字符串操作两个数据帧
【发布时间】:2016-07-06 23:37:08
【问题描述】:

我在这里Finding the index based on two data frames of strings 提出了一个问题,我得到了完美的答案。 现在我遇到了另一个我无法解决的问题。如果我的第二个数据超过一列,那么我可以根据

setDT(strs)[, c('colids1','colids2') := lapply(.SD, function(x) toString(which(colSums(lut == x, na.rm=TRUE) > 0))), by = 1:nrow(strs)][]

只要我的第二个数据(strs)在所有列中的长度相同,就可以了 但如果它们不同(长度不同),那么这不起作用并给我一个错误。

假设我的第一个数据是

lut <- structure(list(V1 = c("O75663", "O95400", "O95433", NA, NA), 
    V2 = c("O95456", "O95670", NA, NA, NA), V3 = c("O75663", 
    "O95400", "O95433", "O95456", "O95670"), V4 = c("O95456", 
    "O95670", "O95801", "P00352", NA), V1 = c("O75663", "O95400", 
    "O95433", NA, NA), V2 = c("O95456", "O95670", NA, NA, NA), 
    V3 = c("O75663", "O95400", "O95433", "O95456", "O95670"), 
    V4 = c("O95456", "O95670", "O95801", "P00352", NA)), .Names = c("V1", 
"V2", "V3", "V4", "V1", "V2", "V3", "V4"), row.names = c(NA, 
-5L), class = "data.frame")

我的第二个数据是

strs <- structure(list(strings = structure(c(2L, 3L, 4L, 5L, 6L, 7L, 
1L, 1L), .Label = c("", "O75663", "O95400", "O95433", "O95456", 
"O95670", "O95801"), class = "factor"), strings2 = structure(c(4L, 
2L, 6L, 5L, 3L, 1L, 1L, 1L), .Label = c("", "O75663", "O95433", 
"O95456", "P00352", "P00492"), class = "factor"), strings3 = structure(c(4L, 
6L, 7L, 8L, 2L, 3L, 5L, 1L), .Label = c("", "O75663", "O95400", 
"O95456", "O95670", "O95801", "P00352", "P00492"), class = "factor"), 
    strings4 = structure(c(2L, 5L, 3L, 4L, 1L, 1L, 1L, 1L), .Label = c("", 
    "O95400", "O95456", "O95801", "P00492"), class = "factor"), 
    strings5 = structure(c(8L, 2L, 7L, 1L, 3L, 6L, 5L, 4L), .Label = c("O75663", 
    "O95400", "O95433", "O95456", "O95670", "O95801", "P00352", 
    "P00492"), class = "factor")), .Names = c("strings", "strings2", 
"strings3", "strings4", "strings5"), class = "data.frame", row.names = c(NA, 
-8L))

这就是我尝试做的事情

df<- setDT(strs)[, paste0('colids_',seq_along(strs)) := lapply(.SD, function(x) toString(which(colSums(lut == x, na.rm=TRUE) > 0))), by = 1:nrow(strs)][]

如果 strs 的长度相同,它可以工作,但当长度不同时,它不起作用,例如我在这里给出的示例

【问题讨论】:

  • 错误很明显。试试这个strs[c(1:3,5)] &lt;- lapply(strs[c(1:3,5)], as.character) 然后运行你的data.table 语句。生成的 df 是否符合您的预期?
  • @Sumedh 感谢您的留言,它并没有解决问题。我按照你说的做了,然后我做了 df 0))), by = 1:nrow(strs)][] 然后我得到了同样的错误。
  • @Sumedh 我一直在尝试网络上的每一条评论,但我不知道为什么它不起作用!!!
  • 抱歉,我第一次使用 strs 数据框一定是做了什么。尝试strs[,c(1:5)] &lt;- lapply(strs[,c(1:5)], as.character),然后运行您的代码。简而言之,将strs数据集中的所有变量从factor转换为character
  • @nik 你必须这样做 strs[]

标签: r


【解决方案1】:

strs 中的因子变量转换为字符变量,也可以使用data.table 轻松完成。假设您的 strs 数据集已经是 data.table,您应该这样做:

strs[, names(strs) := lapply(.SD, as.character)]

如果strs 还不是data.table,你应该使用:

setDT(strs)[, names(strs) := lapply(.SD, as.character)]

之后,您可以按照自己的意愿执行操作。一切都链接在一起,看起来像:

setDT(strs)[, lapply(.SD, as.character)
            ][, paste0('colids_',seq_along(strs)) := lapply(.SD, function(x) toString(which(colSums(lut == x, na.rm=TRUE) > 0))), 
              by = 1:nrow(strs)][]

【讨论】:

  • 非常感谢您的宝贵意见,我已经喜欢您的回答了,太好了!!!可以看看我的真实数据吗?一旦你看,我可以将它们从网络上删除。谢谢
  • 太好了,谢谢兄弟,我也接受了你的回答,因为它提供了很多信息,我从中学到了很多东西。再次感谢
【解决方案2】:

这是我从@scentoni 学来的,rapplylapply 的递归版本,它将所有向量转换为字符。名为 how 的 rapply 模式,如果设置为替换 how = "replace",则列表中的每个元素本身不是列表,并且包含一个类classes 被将 as.character 函数应用到元素的结果替换。

strs <- rapply(strs, as.character, classes="factor", how="replace")

然后执行

df<- setDT(strs)[, paste0('colids_',seq_along(strs)) := lapply(.SD, function(x) toString(which(colSums(lut == x, na.rm=TRUE) > 0))), by = 1:nrow(strs)][]

【讨论】:

  • 这个也有效!!你能评论一下这个功能吗?
猜你喜欢
  • 1970-01-01
  • 2021-01-20
  • 1970-01-01
  • 2021-09-02
  • 2019-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多