Tôi có một danh sách và tôi muốn xóa một yếu tố khỏi nó. Tôi có thể làm cái này như thế nào?
Tôi đã thử tìm kiếm những gì tôi nghĩ rằng tên rõ ràng cho chức năng này sẽ có trong hướng dẫn tham khảo và tôi không tìm thấy bất cứ điều gì phù hợp.
Tôi có một danh sách và tôi muốn xóa một yếu tố khỏi nó. Tôi có thể làm cái này như thế nào?
Tôi đã thử tìm kiếm những gì tôi nghĩ rằng tên rõ ràng cho chức năng này sẽ có trong hướng dẫn tham khảo và tôi không tìm thấy bất cứ điều gì phù hợp.
Câu trả lời:
Tôi hoàn toàn không biết R, nhưng một chút googling sáng tạo đã dẫn tôi đến đây: http://tolstoy.newcastle.edu.au/R/help/05/04/1919.html
Trích dẫn chính từ đó:
Tôi không tìm thấy tài liệu rõ ràng cho R về cách xóa các phần tử khỏi danh sách, nhưng bản dùng thử và lỗi cho tôi biết
myList [[5]] <- NULL
sẽ loại bỏ phần tử thứ 5 và sau đó "đóng" lỗ do xóa phần tử đó. Điều đó đủ cho các giá trị chỉ số, vì vậy tôi phải cẩn thận trong việc loại bỏ các yếu tố. Tôi phải làm việc từ mặt sau của danh sách đến mặt trước.
Một phản hồi cho bài viết đó sau đó trong trạng thái chủ đề :
Để xóa một phần tử của danh sách, xem R FAQ 7.1
Và phần có liên quan của R FAQ nói:
... Không đặt x [i] hoặc x [[i]] thành NULL, vì điều này sẽ xóa thành phần tương ứng khỏi danh sách.
Điều này dường như cho bạn biết (theo cách hơi ngược) làm thế nào để loại bỏ một yếu tố.
Hy vọng rằng sẽ giúp, hoặc ít nhất là dẫn bạn đi đúng hướng.
Error in list[length(list)] <- NULL : replacement has length zero
Nếu bạn không muốn sửa đổi danh sách tại chỗ (ví dụ: để chuyển danh sách có phần tử bị xóa sang hàm), bạn có thể sử dụng lập chỉ mục: chỉ số phủ định có nghĩa là "không bao gồm phần tử này".
x <- list("a", "b", "c", "d", "e"); # example list
x[-2]; # without 2nd element
x[-c(2, 3)]; # without 2nd and 3rd
Ngoài ra, vectơ chỉ số logic rất hữu ích:
x[x != "b"]; # without elements that are "b"
Điều này cũng hoạt động với dataframes:
df <- data.frame(number = 1:5, name = letters[1:5])
df[df$name != "b", ]; # rows without "b"
df[df$number %% 2 == 1, ] # rows with odd numbers only
x$b
theo cách đó và cũng không thể xóa "b" khỏi thành phần danh sách x[[2]] = c("b","k")
.
%in%
để thử nghiệm đối với nhiều mặt hàng. Tôi không chắc ý của bạn là gì bởi không thể xóa x $ b - bạn có nghĩa là xóa toàn bộ cột b
?
Đây là cách loại bỏ phần tử cuối cùng của danh sách trong R:
x <- list("a", "b", "c", "d", "e")
x[length(x)] <- NULL
Nếu x có thể là một vectơ thì bạn sẽ cần tạo một đối tượng mới:
x <- c("a", "b", "c", "d", "e")
x <- x[-length(x)]
Xóa các phần tử Null khỏi danh sách trong một dòng:
x=x[-(which(sapply(x,is.null),arr.ind=TRUE))]
Chúc mừng
x
là một danh sách trống. Sử dụng compact
từ plyr
cho nhiệm vụ này thay thế.
-(which(sapply(x,is.null),arr.ind=TRUE))
trả về named integer(0)
sẽ bỏ hoàn toàn hàng đó.
Tôi muốn thêm rằng nếu đó là một danh sách có tên, bạn có thể chỉ cần sử dụng within
.
l <- list(a = 1, b = 2)
> within(l, rm(a))
$b
[1] 2
Vì vậy, bạn có thể ghi đè lên danh sách ban đầu
l <- within(l, rm(a))
để loại bỏ phần tử có tên a
trong danh sách l
.
within(l, rm(a, b))
Nếu bạn có một danh sách được đặt tên và muốn xóa một yếu tố cụ thể, bạn có thể thử:
lst <- list(a = 1:4, b = 4:8, c = 8:10)
if("b" %in% names(lst)) lst <- lst[ - which(names(lst) == "b")]
Điều này sẽ tạo ra một danh sách lst
với các yếu tố a
, b
, c
. Dòng thứ hai loại bỏ phần tử b
sau khi nó kiểm tra xem nó có tồn tại không (để tránh sự cố @hjv đã đề cập).
hoặc tốt hơn:
lst$b <- NULL
Bằng cách này, không có vấn đề gì khi cố gắng xóa phần tử không tồn tại (ví dụ lst$g <- NULL
)
Có gói danh sách ( http://cran.r-project.org/web/packages/rlist/index.html ) để đối phó với các loại hoạt động danh sách khác nhau.
Ví dụ ( http://cran.r-project.org/web/packages/rlist/vignettes/Filtering.html ):
library(rlist)
devs <-
list(
p1=list(name="Ken",age=24,
interest=c("reading","music","movies"),
lang=list(r=2,csharp=4,python=3)),
p2=list(name="James",age=25,
interest=c("sports","music"),
lang=list(r=3,java=2,cpp=5)),
p3=list(name="Penny",age=24,
interest=c("movies","reading"),
lang=list(r=1,cpp=4,python=2)))
list.remove(devs, c("p1","p2"))
Kết quả trong:
# $p3
# $p3$name
# [1] "Penny"
#
# $p3$age
# [1] 24
#
# $p3$interest
# [1] "movies" "reading"
#
# $p3$lang
# $p3$lang$r
# [1] 1
#
# $p3$lang$cpp
# [1] 4
#
# $p3$lang$python
# [1] 2
Không biết bạn vẫn cần câu trả lời cho vấn đề này hay không nhưng tôi đã tìm thấy từ kinh nghiệm tự học R (có giá trị 3 tuần) của tôi với R rằng, sử dụng NULL
bài tập thực sự sai hoặc không tối ưu, đặc biệt nếu bạn đang cập nhật động một danh sách trong một cái gì đó như một vòng lặp for.
Nói chính xác hơn, sử dụng
myList[[5]] <- NULL
sẽ ném lỗi
myList [[5]] <- NULL: thay thế có độ dài bằng không
hoặc là
nhiều yếu tố được cung cấp hơn là để thay thế
Những gì tôi tìm thấy để làm việc ổn định hơn là
myList <- myList[[-5]]
[[-5]]
nên là dấu ngoặc đơn, nếu không, bạn chỉ bỏ chọn nội dung của phần tử danh sách đó, không phải phần tử. Chà, ít nhất sử dụng dấu ngoặc vuông đôi cho tôi lỗi này: "cố gắng chọn nhiều hơn một phần tử". Những gì làm việc cho tôi là : myList <- myList[-5]
.
Chỉ muốn nhanh chóng thêm (vì tôi không thấy nó trong bất kỳ câu trả lời nào) mà đối với một danh sách có tên, bạn cũng có thể làm l["name"] <- NULL
. Ví dụ:
l <- list(a = 1, b = 2, cc = 3)
l['b'] <- NULL
Sử dụng -
(dấu âm) cùng với vị trí của phần tử, ví dụ nếu phần tử thứ 3 được loại bỏ, hãy sử dụng nó nhưyour_list[-3]
Đầu vào
my_list <- list(a = 3, b = 3, c = 4, d = "Hello", e = NA)
my_list
# $`a`
# [1] 3
# $b
# [1] 3
# $c
# [1] 4
# $d
# [1] "Hello"
# $e
# [1] NA
Xóa phần tử đơn khỏi danh sách
my_list[-3]
# $`a`
# [1] 3
# $b
# [1] 3
# $d
# [1] "Hello"
# $e
[1] NA
Xóa nhiều yếu tố khỏi danh sách
my_list[c(-1,-3,-2)]
# $`d`
# [1] "Hello"
# $e
# [1] NA
my_list[c(-3:-5)]
# $`a`
# [1] 3
# $b
# [1] 3
my_list[-seq(1:2)]
# $`c`
# [1] 4
# $d
# [1] "Hello"
# $e
# [1] NA
Trong trường hợp danh sách được đặt tên, tôi thấy các hàm trợ giúp này hữu ích
member <- function(list,names){
## return the elements of the list with the input names
member..names <- names(list)
index <- which(member..names %in% names)
list[index]
}
exclude <- function(list,names){
## return the elements of the list not belonging to names
member..names <- names(list)
index <- which(!(member..names %in% names))
list[index]
}
aa <- structure(list(a = 1:10, b = 4:5, fruits = c("apple", "orange"
)), .Names = c("a", "b", "fruits"))
> aa
## $a
## [1] 1 2 3 4 5 6 7 8 9 10
## $b
## [1] 4 5
## $fruits
## [1] "apple" "orange"
> member(aa,"fruits")
## $fruits
## [1] "apple" "orange"
> exclude(aa,"fruits")
## $a
## [1] 1 2 3 4 5 6 7 8 9 10
## $b
## [1] 4 5
Còn cái này thì sao? Một lần nữa, sử dụng các chỉ số
> m <- c(1:5)
> m
[1] 1 2 3 4 5
> m[1:length(m)-1]
[1] 1 2 3 4
hoặc là
> m[-(length(m))]
[1] 1 2 3 4
m[1:(length(m) - 1)]
nếu bạn muốn tránh các chỉ số số, bạn có thể sử dụng
a <- setdiff(names(a),c("name1", ..., "namen"))
để xóa tên namea...namen
khỏi a. cái này hoạt động cho danh sách
> l <- list(a=1,b=2)
> l[setdiff(names(l),"a")]
$b
[1] 2
cũng như cho các vectơ
> v <- c(a=1,b=2)
> v[setdiff(names(v),"a")]
b
2