如果列值==“ character(0)”,则从另一列获取值

时间:2019-11-23 16:01:18

标签: r data.table

在以下数据中:

library(stringr)
library(purrr)
entry <- c("P17-Nationalist Revolutionary Movement-Free Bolivia Movement (Movimiento Nacionalista Revolucionario [MNR] - Movimiento Bolivia Libre [MBL] [MNR-MBL])",
           "P18-Socialist Party (Partido Socialista [PS])",
           "P19-Liberty and Justice (Libertad y Justicia [LJ])",
           "")
something <- c(1,2,3,4)
x <- str_match_all(entry, "(?<=\\[).+?(?=\\])") %>% map(drop)
Election_Parties <- tibble::tibble(x, something, entry)

我想用其他列中的值替换character(0)值,如下所示:

setDT(Election_Parties)[identical(x, character(0)) ,x := entry]

但这给了我错误:

Error in `[.data.table`(setDT(Election_Parties), identical(Election_Parties[,  : 
  LHS of := must be a symbol, or an atomic vector (column names or positions).

我在做什么错了?

期望的输出:

library(stringr)
library(purrr)
entry <- c("P17-Nationalist Revolutionary Movement-Free Bolivia Movement (Movimiento Nacionalista Revolucionario [MNR] - Movimiento Bolivia Libre [MBL] [MNR-MBL])",
           "P18-Socialist Party (Partido Socialista [PS])",
           "P19-Liberty and Justice (Libertad y Justicia [LJ])",
           "4")
something <- c(1,2,3,4)
x <- str_match_all(entry, "(?<=\\[).+?(?=\\])") %>% map(drop)
Election_Parties <- tibble::tibble(x, something, entry)

2 个答案:

答案 0 :(得分:1)

Election_Parties[,1]替换为x,将Election_Parties[,3]替换为开始。在data.table内部,应使用列(未加引号)的名称来引用列,而不是通过引用表和列索引来引用。 data.table的简介为here。其次,identical()不是向量化函数,这意味着您不能在i插槽中使用它。例如,

identical(c(1, 1), c(1, 2))
# FALSE

向量化的相等比较应与==进行。如果我们查看?"==",则会看到以下内容:

  

x和y中的至少一个必须是原子向量,但是如果另一个是原子向量,则R试图将其强制转换为原子向量的类型:如果该列表由长度为一的元素组成,则此操作将成功可以强制转换为正确的类型。

因此,正如您正在尝试的那样,我们无法在两个列表之间进行相等比较。在我看来,我想也许x == list(character(0L))会起作用,但是上面的引用表明它不会起作用。

您真正感兴趣的是“列表的长度是否正”。我们可以像这样对x的每一行进行检查。


library(stringr)
library(purrr)
entry <- c("P17-Nationalist Revolutionary Movement-Free Bolivia Movement (Movimiento Nacionalista Revolucionario [MNR] - Movimiento Bolivia Libre [MBL] [MNR-MBL])",
           "P18-Socialist Party (Partido Socialista [PS])",
           "P19-Liberty and Justice (Libertad y Justicia [LJ])",
           "")
something <- c(1,2,3,4)
x <- str_match_all(entry, "(?<=\\[).+?(?=\\])") %>% map(drop)
Election_Parties <- tibble::tibble(x, something, entry)
library(data.table)
#> 
#> Attaching package: 'data.table'
#> The following object is masked from 'package:purrr':
#> 
#>     transpose

Election_Parties[[1]]
#> [[1]]
#> [1] "MNR"     "MBL"     "MNR-MBL"
#> 
#> [[2]]
#> [1] "PS"
#> 
#> [[3]]
#> [1] "LJ"
#> 
#> [[4]]
#> character(0)

setDT(Election_Parties)
# Check lengths of x -- we want to modify zero-length pieces.

Election_Parties[,lengths(x)]
#> [1] 3 1 1 0
Election_Parties[lengths(x) == 0, x := entry]
Election_Parties[[1]]
#> [[1]]
#> [1] "MNR"     "MBL"     "MNR-MBL"
#> 
#> [[2]]
#> [1] "PS"
#> 
#> [[3]]
#> [1] "LJ"
#> 
#> [[4]]
#> [1] ""

编辑:崩溃是由编码问题引起的。我通过将最后一行更改为

来解决了
dt[lengths(x) == 0, x := iconv(entry, sub = "")]

这将删除引起问题的字节-可能是字符 您要保持完全匹配的条目。我认为完全解决此问题可能超出了此问题的范围。

答案 1 :(得分:1)

这将用相同长度的向量中的相应条目替换名为x的列表中的character(0)值:

x[ sapply(x, length)==0 ] <- entry[ sapply(x, length)==0 ]
x
#----------------------
[[1]]
[1] "MNR"     "MBL"     "MNR-MBL"

[[2]]
[1] "PS"

[[3]]
[1] "LJ"

[[4]]
[1] ""

然后可以将其成功转换为我认为是目标的小标题,data.table或dataframe。

以某种方式,列表中的character(0)值(或非值)与NA在向量中的作用相对应。列表还可以包含NULL值或NA。尝试使用identical或'=='均失败,因为这些函数未针对列表参数进行矢量化处理。同样,尝试对字符(0)使用“ ==”也会遇到类似于NA和“ ==”的问题。运行character(0) == character(0)不会返回TRUE,而是返回logical(0)。在if ( )条件表达式中有时也需要测试length == 0。