গতিশীলভাবে character এবং একটি অক্ষর মান ব্যবহার করে ডেটা ফ্রেম কলামগুলি নির্বাচন করুন


120

আমার কাছে বিভিন্ন কলামের নামের একটি ভেক্টর রয়েছে এবং আমি সেই ডেটা.ফ্রেম থেকে সেই কলামটি বের করতে তাদের প্রত্যেকের উপরে লুপ করতে সক্ষম হতে চাই। উদাহরণস্বরূপ, ডেটা সেট mtcarsএবং একটি অক্ষর ভেক্টরে সঞ্চিত কিছু পরিবর্তনশীল নাম বিবেচনা করুন cols। আমি যখন এই কাজের নীচে mtcarsএকটি গতিশীল উপসেট ব্যবহার করে কোনও পরিবর্তনশীল নির্বাচন করার চেষ্টা করিcols

cols <- c("mpg", "cyl", "am")
col <- cols[1]
col
# [1] "mpg"

mtcars$col
# NULL
mtcars$cols[1]
# NULL

আমি কীভাবে এগুলি একই মানগুলিতে ফিরিয়ে আনতে পারি

mtcars$mpg

তবুও আমি সমস্ত কলামগুলিতে colsলুপটি কোনও ধরণের লুপের মান পেতে পারি।

for(x in seq_along(cols)) {
   value <- mtcars[ order(mtcars$cols[x]), ]
}

উত্তর:


181

আপনি এই ধরণের সাবসেটিং করতে পারবেন না $। উত্স কোডে ( R/src/main/subset.c) এতে বলা হয়েছে:

/ * $ সাবসেট অপারেটর।
আমাদের প্রথম যুক্তির মূল্যায়ন করার জন্য আমাদের নিশ্চিত হওয়া দরকার।
দ্বিতীয়টি এমন একটি প্রতীক হবে যা মূল্যায়ন করা দরকার।
* /

দ্বিতীয় যুক্তি? কি?! আপনি বুঝতে পারি যে আছে $আর অন্য সব কিছুর মত, (উদাহরণস্বরূপ সহ (, +, ^ইত্যাদি) একটি ফাংশন, যে আর্গুমেন্ট লাগে এবং মূল্যায়ন করা হয়। df$V1হিসাবে আবার লিখতে পারে

`$`(df , V1)

বা সত্যই

`$`(df , "V1")

কিন্তু ...

`$`(df , paste0("V1") )

... উদাহরণস্বরূপ কখনও কাজ করবে না, বা অন্য যেটি প্রথমে দ্বিতীয় যুক্তিতে মূল্যায়ন করা উচিত। আপনি কেবল একটি স্ট্রিং পাস করতে পারেন যা কখনই মূল্যায়ন হয় না

পরিবর্তে ব্যবহার করুন [(বা [[আপনি যদি ভেক্টর হিসাবে কেবল একটি একক কলামই বের করতে চান)।

উদাহরণ স্বরূপ,

var <- "mpg"
#Doesn't work
mtcars$var
#These both work, but note that what they return is different
# the first is a vector, the second is a data.frame
mtcars[[var]]
mtcars[var]

আপনি do.callকলটি নির্মাণের জন্য লুপগুলি ছাড়াই ক্রম সম্পাদন করতে পারেন order। এখানে নীচে একটি পুনরুত্পাদনযোগ্য উদাহরণ:

#  set seed for reproducibility
set.seed(123)
df <- data.frame( col1 = sample(5,10,repl=T) , col2 = sample(5,10,repl=T) , col3 = sample(5,10,repl=T) )

#  We want to sort by 'col3' then by 'col1'
sort_list <- c("col3","col1")

#  Use 'do.call' to call order. Seccond argument in do.call is a list of arguments
#  to pass to the first argument, in this case 'order'.
#  Since  a data.frame is really a list, we just subset the data.frame
#  according to the columns we want to sort in, in that order
df[ do.call( order , df[ , match( sort_list , names(df) ) ]  ) , ]

   col1 col2 col3
10    3    5    1
9     3    2    2
7     3    2    3
8     5    1    3
6     1    5    4
3     3    4    4
2     4    3    4
5     5    1    4
1     2    5    5
4     5    3    5

এই পরিস্থিতি কি বছরের পর বছর বদলেছে?
ডুনোইস

4

যদি আমি সঠিকভাবে বুঝতে পারি তবে আপনার ভেরিয়েবলের সাথে ভেরিয়েবলের নাম রয়েছে এবং প্রতিটি নামের মাধ্যমে লুপ চান এবং সেগুলি দ্বারা আপনার ডেটা ফ্রেমকে বাছাই করতে চান। যদি তা হয় তবে এই উদাহরণটি আপনার জন্য একটি সমাধান চিত্রিত করে। আপনার প্রাথমিক সমস্যা (সম্পূর্ণ উদাহরণটি সম্পূর্ণ নয় তাই আমি কী জানি যে আপনি কী অনুপস্থিত হতে পারে তা নয়) এটি হ'ল এটির order(Q1_R1000[,parameter[X]])পরিবর্তে হওয়া উচিত order(Q1_R1000$parameter[X]), যেহেতু প্যারামিটার একটি বাহ্যিক অবজেক্ট যা প্রত্যক্ষ কলামের বিপরীতে ভেরিয়েবল নাম ধারণ করে আপনার ডেটা ফ্রেমের (যা কখন $উপযুক্ত হবে)

set.seed(1)
dat <- data.frame(var1=round(rnorm(10)),
                   var2=round(rnorm(10)),
                   var3=round(rnorm(10)))
param <- paste0("var",1:3)
dat
#   var1 var2 var3
#1    -1    2    1
#2     0    0    1
#3    -1   -1    0
#4     2   -2   -2
#5     0    1    1
#6    -1    0    0
#7     0    0    0
#8     1    1   -1
#9     1    1    0
#10    0    1    0

for(p in rev(param)){
   dat <- dat[order(dat[,p]),]
 }
dat
#   var1 var2 var3
#3    -1   -1    0
#6    -1    0    0
#1    -1    2    1
#7     0    0    0
#2     0    0    1
#10    0    1    0
#5     0    1    1
#8     1    1   -1
#9     1    1    0
#4     2   -2   -2

4

Dplyr ব্যবহার করে ডেটা ফ্রেমের বাছাইয়ের জন্য একটি সহজ সিনট্যাক্স সরবরাহ করা হয়

library(dplyr)
mtcars %>% arrange(gear, desc(mpg))

এখানে সাজানো এনএসই সংস্করণটি কার্যকরভাবে সাজানোর তালিকাটি তৈরির অনুমতি হিসাবে ব্যবহার করা কার্যকর হতে পারে

sort_list <- c("gear", "desc(mpg)")
mtcars %>% arrange_(.dots = sort_list)

এনএসই এখানে কী বোঝায়?
অনুষঙ্গ 5

1
@ ডিসিসিপুলাস অ-মানক মূল্যায়ন; এটি হার্ড-কোডিংয়ের পরিবর্তে স্ট্রিং সহ কোডটি গতিময়ভাবে তৈরি করতে বিলম্বিত অভিব্যক্তিগুলির সাথে কাজ করার জন্য। আরও তথ্যের জন্য এখানে দেখুন: cran.r-project.org/web/packages/lazyeval/vignettes/…
manotheshark

1

আর একটি সমাধান হ'ল #get ব্যবহার করা:

> cols <- c("cyl", "am")
> get(cols[1], mtcars)
 [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4

0

একই কলামের বিভিন্ন নাম থাকা কিছু সিএসভি ফাইলের কারণে একই সমস্যা ছিল।
এই সমাধান ছিল:

আমি একটি তালিকায় প্রথম বৈধ কলামের নাম ফেরত দেওয়ার জন্য একটি ফাংশন লিখেছিলাম, তারপরে এটি ব্যবহার করেছি ...

# Return the string name of the first name in names that is a column name in tbl
# else null
ChooseCorrectColumnName <- function(tbl, names) {
for(n in names) {
    if (n %in% colnames(tbl)) {
        return(n)
    }
}
return(null)
}

then...

cptcodefieldname = ChooseCorrectColumnName(file, c("CPT", "CPT.Code"))
icdcodefieldname = ChooseCorrectColumnName(file, c("ICD.10.CM.Code", "ICD10.Code"))

if (is.null(cptcodefieldname) || is.null(icdcodefieldname)) {
        print("Bad file column name")
}

# Here we use the hash table implementation where 
# we have a string key and list value so we need actual strings,
# not Factors
file[cptcodefieldname] = as.character(file[cptcodefieldname])
file[icdcodefieldname] = as.character(file[icdcodefieldname])
for (i in 1:length(file[cptcodefieldname])) {
    cpt_valid_icds[file[cptcodefieldname][i]] <<- unique(c(cpt_valid_icds[[file[cptcodefieldname][i]]], file[icdcodefieldname][i]))
}

0

আপনি যদি নির্দিষ্ট নামের সাথে কলাম নির্বাচন করতে চান তবে ঠিক করুন

A=mtcars[,which(conames(mtcars)==cols[1])]
#and then
colnames(mtcars)[A]=cols[1]

আপনি এটিকে লুপে চালাতে পারেন এবং ডায়নামিক নাম যুক্ত করার জন্য বিপরীত উপায়ে উদাহরণস্বরূপ যদি A ডেটা ফ্রেম হয় এবং xyz কলামটি x হিসাবে নামকরণ করা হয় তবে আমি এটি পছন্দ করি

A$tmp=xyz
colnames(A)[colnames(A)=="tmp"]=x

আবার এটি লুপেও যুক্ত হতে পারে


আমি জানি না কেন নেতিবাচকভাবে ভোট দিয়েছিল, তবে জটিল ফাংশন লেখার পরিবর্তে এটি কার্যকর ও সহজ উপায়
makanand kulkarni


-1

খুব দেরী .. তবে আমার ধারণা আমি উত্তর পেয়েছি -

এখানে আমার নমুনা স্টাডি.ডিএফ ডেটা ফ্রেম -

   >study.df
   study   sample       collection_dt other_column
   1 DS-111 ES768098 2019-01-21:04:00:30         <NA>
   2 DS-111 ES768099 2018-12-20:08:00:30   some_value
   3 DS-111 ES768100                <NA>   some_value

এবং তারপর -

> ## Selecting Columns in an Given order
> ## Create ColNames vector as per your Preference
> 
> selectCols <- c('study','collection_dt','sample')
> 
> ## Select data from Study.df with help of selection vector
> selectCols %>% select(.data=study.df,.)
   study       collection_dt   sample
1 DS-111 2019-01-21:04:00:30 ES768098
2 DS-111 2018-12-20:08:00:30 ES768099
3 DS-111                <NA> ES768100
> 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.