清除包含列表作为变量的列,这些变量在R中为空/NULL/NA?

清除包含列表作为变量的列,这些变量在R中为空/NULL/NA?,r,dataframe,dplyr,tidyverse,R,Dataframe,Dplyr,Tidyverse,给定以下以列表作为值的数据帧: df <- structure(list(keys.userId = c("9875", "5465", "1234", "4567", "8910"), user_data.SSIDs = list( c("qjJf5iZtYboSPvqe1oa/xg==", "ul7kroLEB2cZx6AMGhjnrA==", "OYRT/hYu1Dl3/S5WIWyLHA==", "HFiSH/Tu0RSaQgIbDEZfeA==", "gUBx

给定以下以列表作为值的数据帧:

df <- structure(list(keys.userId = c("9875", "5465", 
"1234", "4567", "8910"), user_data.SSIDs = list(
    c("qjJf5iZtYboSPvqe1oa/xg==", "ul7kroLEB2cZx6AMGhjnrA==", 
    "OYRT/hYu1Dl3/S5WIWyLHA==", "HFiSH/Tu0RSaQgIbDEZfeA==", "gUBxBfxjGdyPNzqYX7t6nA==", 
    "m7UqzqaXUm1GkXMbxf+SJw==", "KjxvZwsVCNSTtXXKiidmjw==", "3UOqe+4qPVZYXvja8GBEqg==", 
    "a9Ba8b19tY/bprM7WA326A==", "uStr9Fg+JlU9B+hdBCafZg==", "i9J11W00HFmoeCDObOfSdA==", 
    "A9vOz8zSrwDiQcKv8hk64Q==", "/8QeMoqFwd/eJ+/6NKk1iQ==", "HbyJqQxUfH6oiW3skqPzGQ==", 
    "51H9RcZmdRgkgg4X6U/mhQ==", "dwat86ppe1b/WXSaGi8r3w==", "yBCbMedxtZdiGFXmTfk2eQ==", 
    "wKSIsw3sDPRQhLIhdQkBJw==", "3LkFUenHOXWL4Be5T4XmaQ==", "Krni6eGQUnZuL/jU0MzKNA==", 
    "Wt9BCH4guyC4oSIHwE8XGA==", "rbgxp/3YPdHiownOdZHf+A==", "34rmNRgT/xFDXIDwHKIY6Q==", 
    "pT3zFcGdlJKmR+khJLMoVw==", "eni3X9I2B4KRK+sho2MbjA==", "sxuba/1Brg4CrYL8AFv8ZQ==", 
    "EYIxPOXPVvop99YD0vjXPA==", "JC1xqrtmQEaohwzviYDFYA==", "qv+cfEEqsIGrDFuEqpkQuw==", 
    "d3xXMR1RDKZdrDwQd97kNQ==", "qU1JULumBTqw+m/rLr4E7A==", "teDCJvNdyjktWD6leDpCmw==", 
    "ytSBHvzbEACq56aEHZlXEw==", "eV7WGimPD01weRI19ojO3g==", "vNkJyD9KOzOprGkYyfViMA==", 
    "r8jjZXWyax7JPfJUPFwRTQ==", "rJ1N3ONwDBK+jwFf+7xeHg==", "2xPbTqIww1KI/tVL2UH1cw==", 
    "1hk1AOU4DZXV52Auyr2FHA==", "aNH8uS5nrlwcHb8rLdZeXQ==", "5JPQs2z4N1Dru0dGI9ImBQ==", 
    "nbQIn5G4uyl8b1+A6aVkQg==", "A/UcwEccakKDuiATgoP1NA==", "JC57Ib2V7fOU/CgBk2R41g==", 
    "PsI8Ys++JveA+SuafbB8pg==", "eXiuBymYN+tcbjtpM9Vxmg==", "jEdP3Rs02d/4UE8G1GeE3A=="
    ), NULL, c("qjJf5iZtYboSPvqe1oa/xg==", "ul7kroLEB2cZx6AMGhjnrA==", 
    "OYRT/hYu1Dl3/S5WIWyLHA==", "HFiSH/Tu0RSaQgIbDEZfeA==", "gUBxBfxjGdyPNzqYX7t6nA==", 
    "m7UqzqaXUm1GkXMbxf+SJw==", "KjxvZwsVCNSTtXXKiidmjw==", "3UOqe+4qPVZYXvja8GBEqg==", 
    "a9Ba8b19tY/bprM7WA326A==", "uStr9Fg+JlU9B+hdBCafZg==", "i9J11W00HFmoeCDObOfSdA==", 
    "A9vOz8zSrwDiQcKv8hk64Q==", "/8QeMoqFwd/eJ+/6NKk1iQ==", "HbyJqQxUfH6oiW3skqPzGQ==", 
    "51H9RcZmdRgkgg4X6U/mhQ==", "dwat86ppe1b/WXSaGi8r3w==", "yBCbMedxtZdiGFXmTfk2eQ==", 
    "wKSIsw3sDPRQhLIhdQkBJw==", "3LkFUenHOXWL4Be5T4XmaQ==", "Krni6eGQUnZuL/jU0MzKNA==", 
    "Wt9BCH4guyC4oSIHwE8XGA==", "rbgxp/3YPdHiownOdZHf+A==", "34rmNRgT/xFDXIDwHKIY6Q==", 
    "pT3zFcGdlJKmR+khJLMoVw==", "eni3X9I2B4KRK+sho2MbjA==", "sxuba/1Brg4CrYL8AFv8ZQ==", 
    "EYIxPOXPVvop99YD0vjXPA==", "JC1xqrtmQEaohwzviYDFYA==", "qv+cfEEqsIGrDFuEqpkQuw==", 
    "d3xXMR1RDKZdrDwQd97kNQ==", "qU1JULumBTqw+m/rLr4E7A==", "teDCJvNdyjktWD6leDpCmw==", 
    "ytSBHvzbEACq56aEHZlXEw==", "eV7WGimPD01weRI19ojO3g==", "vNkJyD9KOzOprGkYyfViMA==", 
    "r8jjZXWyax7JPfJUPFwRTQ==", "rJ1N3ONwDBK+jwFf+7xeHg==", "2xPbTqIww1KI/tVL2UH1cw==", 
    "1hk1AOU4DZXV52Auyr2FHA==", "aNH8uS5nrlwcHb8rLdZeXQ==", "5JPQs2z4N1Dru0dGI9ImBQ==", 
    "nbQIn5G4uyl8b1+A6aVkQg==", "A/UcwEccakKDuiATgoP1NA==", "JC57Ib2V7fOU/CgBk2R41g==", 
    "PsI8Ys++JveA+SuafbB8pg==", "eXiuBymYN+tcbjtpM9Vxmg==", "jEdP3Rs02d/4UE8G1GeE3A=="
    ), NULL, c("qjJf5iZtYboSPvqe1oa/xg==", "ul7kroLEB2cZx6AMGhjnrA==", 
    "OYRT/hYu1Dl3/S5WIWyLHA==", "HFiSH/Tu0RSaQgIbDEZfeA==", "gUBxBfxjGdyPNzqYX7t6nA==", 
    "m7UqzqaXUm1GkXMbxf+SJw==", "KjxvZwsVCNSTtXXKiidmjw==", "3UOqe+4qPVZYXvja8GBEqg==", 
    "a9Ba8b19tY/bprM7WA326A==", "uStr9Fg+JlU9B+hdBCafZg==", "i9J11W00HFmoeCDObOfSdA==", 
    "A9vOz8zSrwDiQcKv8hk64Q==", "/8QeMoqFwd/eJ+/6NKk1iQ==", "HbyJqQxUfH6oiW3skqPzGQ==", 
    "51H9RcZmdRgkgg4X6U/mhQ==", "dwat86ppe1b/WXSaGi8r3w==", "yBCbMedxtZdiGFXmTfk2eQ==", 
    "wKSIsw3sDPRQhLIhdQkBJw==", "3LkFUenHOXWL4Be5T4XmaQ==", "Krni6eGQUnZuL/jU0MzKNA==", 
    "Wt9BCH4guyC4oSIHwE8XGA==", "rbgxp/3YPdHiownOdZHf+A==", "34rmNRgT/xFDXIDwHKIY6Q==", 
    "pT3zFcGdlJKmR+khJLMoVw==", "eni3X9I2B4KRK+sho2MbjA==", "sxuba/1Brg4CrYL8AFv8ZQ==", 
    "EYIxPOXPVvop99YD0vjXPA==", "JC1xqrtmQEaohwzviYDFYA==", "qv+cfEEqsIGrDFuEqpkQuw==", 
    "d3xXMR1RDKZdrDwQd97kNQ==", "qU1JULumBTqw+m/rLr4E7A==", "teDCJvNdyjktWD6leDpCmw==", 
    "ytSBHvzbEACq56aEHZlXEw==", "eV7WGimPD01weRI19ojO3g==", "vNkJyD9KOzOprGkYyfViMA==", 
    "r8jjZXWyax7JPfJUPFwRTQ==", "rJ1N3ONwDBK+jwFf+7xeHg==", "2xPbTqIww1KI/tVL2UH1cw==", 
    "1hk1AOU4DZXV52Auyr2FHA==", "aNH8uS5nrlwcHb8rLdZeXQ==", "5JPQs2z4N1Dru0dGI9ImBQ==", 
    "nbQIn5G4uyl8b1+A6aVkQg==", "A/UcwEccakKDuiATgoP1NA==", "JC57Ib2V7fOU/CgBk2R41g==", 
    "PsI8Ys++JveA+SuafbB8pg==", "eXiuBymYN+tcbjtpM9Vxmg==", "jEdP3Rs02d/4UE8G1GeE3A=="
    )), user_data.contacts = list(list(), NULL, list(), NULL, 
    list())), row.names = c(NA, 5L), class = "data.frame")
但它到处都是假的

有什么方法可以正确有效地完成这项工作吗?请告知

最后,清洁后,我将运行:

df %>% 
  cleaning %>%
dplyr::mutate(contacts_jaccard = jaccardV(user_data.contacts, lag(user_data.contacts)))

这将是一种方法:

library(dplyr)
library(purrr)
df %>% 
  filter(!map_lgl(user_data.contacts, is.null)) %>% 
  filter(!map_lgl(user_data.contacts, function(x) length(x) == 0)) %>% 
  filter(!map_lgl(user_data.contacts, is.na)) %>% 
  mutate(contacts_jaccard = jaccardV(user_data.contacts, lag(user_data.contacts)))
这不会产生任何输出,因为在您提供的模拟数据中,所有行现在都已删除。如果只是为了以后删除行,则无需创建新列
isNull
。我开始更喜欢
map
而不是
sapply
,因为强制实现某个结果非常容易。在这种情况下,
map\u lgl
只会产生正确/错误的结果

请注意,如果列表列的一个元素长度大于1,则应改为使用:

df %>% 
  filter(!map_lgl(user_data.contacts, is.null)) %>% 
  filter(!map_lgl(user_data.contacts, function(x) length(x) == 0)) %>% 
  filter(!map_lgl(user_data.contacts, function(x) is.na(x)[1])) %>% 
  mutate(contacts_jaccard = jaccardV(user_data.contacts, lag(user_data.contacts)))

这将是一种方法:

library(dplyr)
library(purrr)
df %>% 
  filter(!map_lgl(user_data.contacts, is.null)) %>% 
  filter(!map_lgl(user_data.contacts, function(x) length(x) == 0)) %>% 
  filter(!map_lgl(user_data.contacts, is.na)) %>% 
  mutate(contacts_jaccard = jaccardV(user_data.contacts, lag(user_data.contacts)))
这不会产生任何输出,因为在您提供的模拟数据中,所有行现在都已删除。如果只是为了以后删除行,则无需创建新列
isNull
。我开始更喜欢
map
而不是
sapply
,因为强制实现某个结果非常容易。在这种情况下,
map\u lgl
只会产生正确/错误的结果

请注意,如果列表列的一个元素长度大于1,则应改为使用:

df %>% 
  filter(!map_lgl(user_data.contacts, is.null)) %>% 
  filter(!map_lgl(user_data.contacts, function(x) length(x) == 0)) %>% 
  filter(!map_lgl(user_data.contacts, function(x) is.na(x)[1])) %>% 
  mutate(contacts_jaccard = jaccardV(user_data.contacts, lag(user_data.contacts)))

我想这应该对你有用。浏览contacts列,创建一个新列,告知它是否为null,然后根据新列筛选它们

library(tidyverse)

new_df <- df %>%as_tibble() %>%
    mutate(is_Null = sapply(user_data.contacts, is_null)) %>%
    filter(is_Null == FALSE)

new_df
库(tidyverse)
新的_df%作为_tible()%>%
mutate(is_Null=sapply(user_data.contacts,is_Null))%>%
筛选器(is_Null==FALSE)
新德里

我认为这应该适合你。浏览contacts列,创建一个新列,告知它是否为null,然后根据新列筛选它们

library(tidyverse)

new_df <- df %>%as_tibble() %>%
    mutate(is_Null = sapply(user_data.contacts, is_null)) %>%
    filter(is_Null == FALSE)

new_df
库(tidyverse)
新的_df%作为_tible()%>%
mutate(is_Null=sapply(user_data.contacts,is_Null))%>%
筛选器(is_Null==FALSE)
新德里

user\u data.contacts
是一个列表,当您更改该列时,它将其视为一个列表。在
mutate
之前,尝试将数据按行分组

library(dplyr)

df %>% 
  rowwise() %>% 
  mutate(isNull = is.null(unlist(user_data.contacts)))


# A tibble: 5 x 4 # added data to 1st observation for test
  keys.userId user_data.SSIDs user_data.contacts isNull
  <chr>       <list>          <list>             <lgl> 
1 9875        <chr [47]>      <list [3]>         FALSE 
2 5465        <NULL>          <NULL>             TRUE  
3 1234        <chr [47]>      <list [0]>         TRUE  
4 4567        <NULL>          <NULL>             TRUE  
5 8910        <chr [47]>      <list [0]>         TRUE
库(dplyr)
df%>%
行()
mutate(isNull=is.null(未列出(用户\数据.联系人)))
#TIBLE:5 x 4#将数据添加到测试的第一次观察中
keys.userId user_data.SSIDs user_data.contacts为空
19875错
25465对
31234对
44567对
58910对

user\u data.contacts
是一个列表,当您更改该列时,它将其视为一个列表。在
mutate
之前,尝试将数据按行分组

library(dplyr)

df %>% 
  rowwise() %>% 
  mutate(isNull = is.null(unlist(user_data.contacts)))


# A tibble: 5 x 4 # added data to 1st observation for test
  keys.userId user_data.SSIDs user_data.contacts isNull
  <chr>       <list>          <list>             <lgl> 
1 9875        <chr [47]>      <list [3]>         FALSE 
2 5465        <NULL>          <NULL>             TRUE  
3 1234        <chr [47]>      <list [0]>         TRUE  
4 4567        <NULL>          <NULL>             TRUE  
5 8910        <chr [47]>      <list [0]>         TRUE
库(dplyr)
df%>%
行()
mutate(isNull=is.null(未列出(用户\数据.联系人)))
#TIBLE:5 x 4#将数据添加到测试的第一次观察中
keys.userId user_data.SSIDs user_data.contacts为空
19875错
25465对
31234对
44567对
58910对

是否要删除空列?还是要用其他内容替换空值?@HarroCyranka正如我前面所说,每列都有list(NULL)、list(0)、list(NA),我想删除这些行。pull函数在UseMethod(“pull”)中返回一个错误:没有适用于“pull”的方法应用于类“list”@HarroCyranka PERFECTO的对象!因此,sapply只获取了user_data.contacts(=列表)列的每个元素,对于该列表的每个元素,它都返回TRUE/FALSE,因此如果将NA/NULL作为内部列表的一部分,我应该考虑忽略它们的逻辑。是否要删除NULL列?还是要用其他内容替换空值?@HarroCyranka正如我前面所说,每列都有list(NULL)、list(0)、list(NA),我想删除这些行。pull函数在UseMethod(“pull”)中返回一个错误:没有适用于“pull”的方法应用于类“list”@HarroCyranka PERFECTO的对象!所以sapply只取了user_data.contacts(=一个列表)列的每个元素,对于这个列表的每个元素,它都返回TRUE/FALSE,所以如果我将NA/NULL作为内部列表的一部分,我应该考虑忽略它们的逻辑。
is_NULL==FALSE
有点笨拙。您可以通过
实现同样的功能!是空的
.PERFECTO!所以sapply只取了user_data.contacts(=一个列表)列的每个元素,对于这个列表的每个元素,它都返回TRUE/FALSE,所以如果我将NA/NULL作为内部列表的一部分,我应该考虑忽略它们的逻辑。我将更改我的响应以处理NA值
is_NULL==FALSE
有点笨拙。您可以通过
实现同样的功能!是空的
.PERFECTO!因此,sapply只获取了user_data.contacts(=列表)列中的每个元素,对于该列表的每个元素,它都返回TRUE/FALSE,因此如果内部列表中有NA/NULL,我应该考虑忽略它们的逻辑。我将更改响应以处理NA值
ifelse()
TRUE
FALSE
是多余的。您可以单独使用
is.null
。另外,如果列表的一行中有多个条目,
unlist
将不起作用。我只是给OP一个前进的方向。关于
ifelse()
is.null(unlist(user\u data.contacts))就足够了。我不确定你关于
未列出
的陈述是什么意思。
ifelse()
TRUE
FALSE
是多余的。您可以单独使用
is.null
。另外,如果列表的一行中有多个条目,
unlist
将不起作用。我只是给OP一个前进的方向。关于
ifelse,您是对的(